Skip to content
/ Cydia Public
forked from XLsn0w/Cydiapps

๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅๅพฎไฟกๅ…ฌไผ—ๅท: XLsnow๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ=> Cydiaๆ’ไปถ Logos่ฏญ่จ€ ๅผ€ๅ‘Tweak.xm Cydia Substrate ๆณจๅ…ฅdylib iOS้€†ๅ‘ๅทฅ็จ‹ๅผ€ๅ‘ ่ถŠ็‹ฑJailbreak debๆ’ไปถ - fishhook / Frida / iOSOpenDev / Cycript / MachOView / IDA / Hopper Disassembler / MonkeyDev / Class-dump / Theos / Reveal / Dumpdecryptd / FLEX / ๆฑ‡็ผ–Assembly / CaptainHook / lldb/LLVM/XNU/Darwin/iOS Reverse

License

Notifications You must be signed in to change notification settings

DK3369/Cydia

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

iOS้€†ๅ‘ๅทฅ็จ‹ๅผ€ๅ‘ ่ถŠ็‹ฑJailbreak Cydia debๆ’ไปถๅผ€ๅ‘

touch4

SE

ๆˆ‘็š„ๅพฎไฟกๅ…ฌไผ—ๅท: Cydiapple

cydiapple

Cycript / Class-dump / Theos / Reveal / Dumpdecrypted ้€†ๅ‘ๅทฅๅ…ทไฝฟ็”จไป‹็ป

่ถŠ็‹ฑๅผ€ๅ‘ๅธธ่ง็š„ๅทฅๅ…ทOpenSSH๏ผŒDumpdecrypted๏ผŒclass-dumpใ€Theosใ€Revealใ€IDA๏ผŒHopper๏ผŒ

ๆทปๅŠ ๆˆ‘็š„GithubไธชไบบCydiaๆ’ไปถๆบ:

https://xlsn0w.github.io/CydiaRepo
https://xlsn0w.github.io/ipas
//                     _0_
//                   _oo0oo_
//                  o8888888o
//                  88" . "88
//                  (| -_- |)
//                  0\  =  /0
//                ___/`---'\___
//              .' \\|     |// '.
//             / \\|||  :  |||// \
//            / _||||| -:- |||||- \
//           |   | \\\  -  /// |   |
//           | \_|  ''\---/''  |_/ |
//           \  .-\__  '-'  ___/-. /
//         ___'. .'  /--.--\  `. .'___
//      ."" '<  `.___\_<|>_/___.' >' "".
//     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
//     \  \ `_.   \_ __\ /__ _/   .-` /  /
// XL---`-.____`.___ \_____/___.-`___.-'---sn0w
//                   `=---='

CydiaRepo

iOS Jailbreak Material - ๆŽจ่้˜…่ฏปiOS่ถŠ็‹ฑ่ต„ๆ–™

ๆธ…ๅ•:

iOS 8.4.1 Yalu Open Source Jailbreak Project: https://github.com/kpwn/yalu

OS-X-10.11.6-Exp-via-PEGASUS: https://github.com/zhengmin1989/OS-X-10.11.6-Exp-via-PEGASUS

iOS 9.3.* Trident exp: https://github.com/benjamin-42/Trident

iOS 10.1.1 mach_portal incomplete jailbreak: https://bugs.chromium.org/p/project-zero/issues/detail?id=965#c2

iOS 10.2 jailbreak source code: https://github.com/kpwn/yalu102

Local Privilege Escalation for macOS 10.12.2 and XNU port Feng Shui: https://github.com/zhengmin1989/macOS-10.12.2-Exp-via-mach_voucher

Remotely Compromising iOS via Wi-Fi and Escaping the Sandbox: https://www.youtube.com/watch?v=bP5VP7vLLKo

Pwn2Own 2017 Safari sandbox: https://github.com/maximehip/Safari-iOS10.3.2-macOS-10.12.4-exploit-Bugs

Live kernel introspection on iOS: https://bazad.github.io/2017/09/live-kernel-introspection-ios/

iOS 11.1.2 IOSurfaceRootUserClient double free to tfp0: https://bugs.chromium.org/p/project-zero/issues/detail?id=1417

iOS 11.3.1 MULTIPATH kernel heap overflow to tfp0: https://bugs.chromium.org/p/project-zero/issues/detail?id=1558

iOS 11.3.1 empty_list kernel heap overflow to tfp0: https://bugs.chromium.org/p/project-zero/issues/detail?id=1564
$ touch .gitattributes

ๆทปๅŠ ๆ–‡ไปถๅ†…ๅฎนไธบ

*.h linguist-language=Logos
*.m linguist-language=Logos 

ๅซไน‰ๅณๅฐ†ๆ‰€ๆœ‰็š„.mๆ–‡ไปถ่ฏ†ๅˆซๆˆLogos๏ผŒไนŸๅฏๆทปๅŠ ๅคš่กŒ็›ธๅบ”็š„ๅ†…ๅฎนไปŽ่€Œไฟฎๆ”นๅˆฐๅ ๆฏ”๏ผŒไปŽ่€Œๆ”นๅ˜GitHub้กน็›ฎ่ฏ†ๅˆซ่ฏญ่จ€

theos ็š„ไธ€ไบ›ไบ‹

( Logos is a component of the Theos development suite that allows method hooking code to be written easily and clearly, using a set of special preprocessor directives. ) Logosๆ˜ฏTheosๅผ€ๅ‘ๅฅ—ไปถ็š„ไธ€ไธช็ป„ไปถ๏ผŒ่ฏฅๅฅ—ไปถๅ…่ฎธไฝฟ็”จไธ€็ป„็‰นๆฎŠ็š„้ข„ๅค„็†็จ‹ๅบๆŒ‡ไปค่ฝปๆพ่€Œๆธ…ๆ™ฐๅœฐ็ผ–ๅ†™ๆ–นๆณ•ๆŒ‚้’ฉไปฃ็ ใ€‚

This is an Logos ่ฏญๆณ•ไป‹็ป.

// ไฝฟ็”จ-switch้€‰้กนๅฏๅฐ†็ณป็ปŸไธŠ็š„Xcodeๆ›ดๆ”นไธบๅฆไธ€ไธช็‰ˆๆœฌ๏ผš $ sudo xcode-select --switch /Applications/Xcode.app $ sudo xcode-select -switch /Applications/Xcode.app

ๅฎ‰่ฃ…ๅ‘ฝไปค

$ export THEOS=/opt/theos        
$ sudo git clone git://github.com/DHowett/theos.git $THEOS

ๅฎ‰่ฃ…ldid ็ญพๅๅทฅๅ…ท

http://joedj.net/ldid  ็„ถๅŽๅคๅˆถๅˆฐ/opt/theos/bin 
็„ถๅŽsudo chmod 777 /opt/theos/bin/ldid

้…็ฝฎCydiaSubstrate ็”จiTools,ๅฐ†iOSไธŠ

/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate

ๆ‹ท่ดๅˆฐ็”ต่„‘ไธŠ, ็„ถๅŽๆ”นๅไธบlibsubstrate.dylib , ็„ถๅŽๆ‹ท่ดๅˆฐ/opt/theos/lib ไธญ.

ๅฎ‰่ฃ…็ฅžๅ™จdkpg

$ sudo port install dpkg

//ไธ้œ€่ฆๅ†ไธ‹่ฝฝ้‚ฃไธชdpkg-debไบ†

ๅขžๅŠ nic-templates(ๅฏ้€‰)

ไปŽ https://github.com/DHowett/theos-nic-templates ไธ‹่ฝฝ 

็„ถๅŽๅฐ†่งฃๅŽ‹ๅŽ็š„5ไธช.tarๆ”พๅˆฐ/opt/theos/templates/ios/ไธ‹ๅณๅฏ

ๅˆ›ๅปบdeb tweak

/opt/theos/bin/nic.pl

NIC 1.0 - New Instance Creator
โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”
  [1.] iphone/application
  [2.] iphone/library
  [3.] iphone/preference_bundle
  [4.] iphone/tool
  [5.] iphone/tweak
Choose a Template (required): 1
Project Name (required): firstdemo
Package Name [com.yourcompany.firstdemo]: 
Author/Maintainer Name [Author Name]: 
Instantiating iphone/application in firstdemo/โ€ฆ
Done.

้€‰ๆ‹ฉ [5.] iphone/tweak

Project Name (required): Test
Package Name [com.yourcompany.test]: com.test.firstTest
Author/Maintainer Name [ๅฐไผ]: xiaowu
[iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]: com.apple.springboard
[iphone/tweak] List of applications to terminate upon installation (space-separated, '-' for none) [SpringBoard]: SpringBoard

็ฌฌไธ€ไธช็›ธๅฝ“ไบŽๅทฅ็จ‹ๆ–‡ไปถๅคน็š„ๅๅญ— ็ฌฌไบŒไธช็›ธๅฝ“ไบŽbundle id ็ฌฌไธ‰ไธชๅฐฑๆ˜ฏไฝœ่€… ็ฌฌๅ››ไธชๆ˜ฏไฝœ็”จๅฏน่ฑก็š„bundle identifier ็ฌฌไบ”ไธชๆ˜ฏ่ฆ้‡ๅฏ็š„ๅบ”็”จ b.ไฟฎๆ”นMakefile

TWEAK_NAME = iOSRE
iOSRE_FILES = Tweak.xm
include $(THEOS_MAKE_PATH)/tweak.mk
THEOS_DEVICE_IP = 192.168.1.34
iOSRE_FRAMEWORKS=UIKit Foundation
ARCHS = arm64

ไธŠ้ข็š„ipๅฟ…้กปๅ†™, ๅฝ“็„ถๅ†™ไฝ ๆต‹่ฏ•ๆœบ็š„ip , ็„ถๅŽarchs ๅ†™ไฝ ๆƒณ็”Ÿๆˆๅฏนๅบ”ๆœบๅž‹็š„ๅž‹ๅท

c.ไพฟๆบTweak.xm

#import <UIKit/UIKit.h>
#import <SpringBoard/SpringBoard.h>

%hook SpringBoard

-(void)applicationDidFinishLaunching:(id)application {

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Welcome"
message:@"Welcome to your iPhone!"
delegate:nil
cancelButtonTitle:@"Thanks"
otherButtonTitles:nil];
[alert show];
[alert release];
%orig;

}

%end

ไฝ ้ป˜่ฎค็š„Tweak.xm้‡Œ้ข็š„ไปฃ็ ้ƒฝๆ˜ฏ่ขซๆณจ้”€็š„

d.่ฎพ็ฝฎ็Žฏๅขƒๅ˜้‡ ๆ‰“ๅผ€terminal่พ“ๅ…ฅ

export THEOS=/opt/theos/
export THEOS_DEVICE_IP=xxx.xxx.xxx.xxx(ๆ‰‹ๆœบ็š„ipๅœฐๅ€)

3.ๆž„ๅปบๅทฅ็จ‹

็ฌฌไธ€ไธชๅ‘ฝไปค:make

$ make
Making all for application firstdemoโ€ฆ
 Compiling main.mโ€ฆ
 Compiling firstdemoApplication.mmโ€ฆ
 Compiling RootViewController.mmโ€ฆ
 Linking application firstdemoโ€ฆ
 Stripping firstdemoโ€ฆ
 Signing firstdemoโ€ฆ

็ฌฌไบŒไธชๅ‘ฝไปค:make package

make package
Making all for application firstdemoโ€ฆ
make[2]: Nothing to be done for โ€˜internal-application-compileโ€™.
Making stage for application firstdemoโ€ฆ
 Copying resource directories into the application wrapperโ€ฆ
dpkg-deb: building package โ€˜com.yourcompany.firstdemoโ€™ in โ€˜/Users/author/Desktop/firstdemo/com.yourcompany.firstdemo_0.0.1-1_iphoneos-arm.debโ€™.

็ฌฌไธ‰ไธชๅ‘ฝไปค: make package install

$ make package install
Making all for application firstdemoโ€ฆ
make[2]: Nothing to be done for `internal-application-compileโ€™.
Making stage for application firstdemoโ€ฆ
 Copying resource directories into the application wrapperโ€ฆ
dpkg-deb: building package โ€˜com.yourcompany.firstdemoโ€™ in โ€˜/Users/author/Desktop/firstdemo/com.yourcompany.firstdemo_0.0.1-1_iphoneos-arm.debโ€™.
...
root@ipโ€™s password: 
...

่ฟ‡็จ‹ไผš่ฎฉไฝ ่พ“ๅ…ฅไธคๆฌกiphoenๅฏ†็  , ้ป˜่ฎคๆ˜ฏalpine

** ๅฝ“็„ถไฝ ไนŸๅฏไปฅ็›ดๆŽฅ make package install ไธ€ๆญฅๅˆฐไฝ, ็›ดๆŽฅ็ผ–่ฏ‘, ๆ‰“ๅŒ…, ๅฎ‰่ฃ…ไธ€ๆฐ”ๅ‘ตๆˆ**

่ฏดไธ€่ฏด ้‡ๅˆฐ็š„ๅ‘

1.ๅœจ ็Žฏๅขƒๅฎ‰่ฃ… ็š„็ฌฌไบŒๆญฅ้ชค ไธ‹่ฝฝtheos , ไธ‹่ฝฝๅฅฝ็š„theosๆœ‰ๅฏ่ƒฝๆ˜ฏๆœ‰้—ฎ้ข˜็š„

/opt/theos/vendor/ ้‡Œ้ข็š„ๆ–‡ไปถๆ˜ฏๅฆๆ˜ฏ็ฉบ็š„? ไป”็ป†ๆฃ€ๆŸฅ ๅฆๅˆ™ๅœจmake็ผ–่ฏ‘็š„ๆ—ถๅ€™ๅ›žๆŠฅไธ€ไธช ไป€ไนˆvendor ็š„้”™่ฏฏ 2.ๅฆ‚ๆžœๅœจmakeๆˆๅŠŸไน‹ๅŽ่ฟ˜ๆƒณmake ๅ‘็ŽฐๆŠฅไบ†Nothing to be done for `internal-library-compileโ€™้”™่ฏฏ

้‚ฃๅฐฑๆŠŠไฝ ๅˆšๆ‰ๅˆ›ๅปบๅ‡บๆฅ็š„objๅˆ ๆŽ‰ๅ’Œpackagesๅˆ ๆŽ‰ , ็„ถๅŽๆ˜พ็คบ้š่—ๆ–‡ไปถ, ไฝ ๅฐฑไผšๅ‘็Žฐๅ’ŒobjๅŒไธ€ไธช็›ฎๅฝ•ๆœ‰ไธ€ไธช.theos , ๅง.theos้‡Œ้ข็š„ไธœ่ฅฟๅˆ ๆŽ‰ๅฐฑๅฅฝไบ† 3.็ฎ€ๅ•ๆ€ป็ป“ไธ‹

ๅŸบๆœฌ้—ฎ้ข˜ๅฐฑไธ€ไธ‹ๅ‡ ็‚น: 1.ไปฃ็ %hook ClassName ๆฒกๆœ‰ไฟฎๆ”น 2.ไปฃ็ ๆฒก่ฐƒ็”จๅคดๆ–‡ไปถ 3.ไปฃ็ ๆณจ้‡Šๆฒกๆœ‰่งฃๅผ€(ไปฃ็ ๅ†™้”™) 4.makefile้‡Œ้ขไธœ่ฅฟๅ†™้”™ 5.makefile้‡Œ้ขๆฒกๆœ‰ๅ†™ipๅœฐๅ€ 6.ๆฒกๆœ‰้…็ฝฎ็Žฏๅขƒๅœฐๅ€ 7.้‡ๅˆฐ่ทฏๅพ„็š„้—ฎ้ข˜ไฝ ๅฐฑ export THEOS_DEVICE_IP=192.168.1.34 8.้‡ๅˆฐ่ทฏๅพ„้—ฎ้ข˜ไฝ ๅฐฑTHEOS=/opt/theos

ๆ’ไปถๅผ€ๅ‘(.xm)

dpkg -i package.deb #ๅฎ‰่ฃ…ๅŒ… dpkg -r package #ๅˆ ้™คๅŒ… dpkg -P package #ๅˆ ้™คๅŒ…๏ผˆๅŒ…ๆ‹ฌ้…็ฝฎๆ–‡ไปถ๏ผ‰ dpkg -L package #ๅˆ—ๅ‡บไธŽ่ฏฅๅŒ…ๅ…ณ่”็š„ๆ–‡ไปถ dpkg -l package #ๆ˜พ็คบ่ฏฅๅŒ…็š„็‰ˆๆœฌ dpkg --unpack package.deb #่งฃๅผ€debๅŒ…็š„ๅ†…ๅฎน dpkg -S keyword #ๆœ็ดขๆ‰€ๅฑž็š„ๅŒ…ๅ†…ๅฎน dpkg -l #ๅˆ—ๅ‡บๅฝ“ๅ‰ๅทฒๅฎ‰่ฃ…็š„ๅŒ… dpkg -c package.deb #ๅˆ—ๅ‡บdebๅŒ…็š„ๅ†…ๅฎน dpkg --configure package #้…็ฝฎๅŒ…

deb ๅคงๆฆ‚็ป“ๆž„

ๅ…ถไธญๅŒ…ๆ‹ฌ๏ผšDEBIAN็›ฎๅฝ• ๅ’Œ ่ฝฏไปถๅ…ทไฝ“ๅฎ‰่ฃ…็›ฎๅฝ•๏ผˆๆจกๆ‹Ÿๅฎ‰่ฃ…็›ฎๅฝ•๏ผ‰๏ผˆๅฆ‚etc, usr, opt, tmp็ญ‰๏ผ‰ใ€‚ ๅœจDEBIAN็›ฎๅฝ•ไธญ่‡ณๅฐ‘ๆœ‰controlๆ–‡ไปถ๏ผŒ่ฟ˜ๅฏ่ƒฝๆœ‰postinst(postinstallation)ใ€postrm(postremove)ใ€preinst(preinstallation)ใ€prerm(preremove)ใ€copyright (็‰ˆๆƒ๏ผ‰ใ€changlog ๏ผˆไฟฎ่ฎข่ฎฐๅฝ•๏ผ‰ๅ’Œconffiles็ญ‰ใ€‚

postinstๆ–‡ไปถ๏ผšๅŒ…ๅซไบ†่ฝฏไปถๅœจ่ฟ›่กŒๆญฃๅธธ็›ฎๅฝ•ๆ–‡ไปถๆ‹ท่ดๅˆฐ็ณป็ปŸๅŽ๏ผŒๆ‰€้œ€่ฆๆ‰ง่กŒ็š„้…็ฝฎๅทฅไฝœใ€‚ prermๆ–‡ไปถ๏ผš่ฝฏไปถๅธ่ฝฝๅ‰้œ€่ฆๆ‰ง่กŒ็š„่„šๆœฌใ€‚ postrmๆ–‡ไปถ๏ผš่ฝฏไปถๅธ่ฝฝๅŽ้œ€่ฆๆ‰ง่กŒ็š„่„šๆœฌใ€‚ controlๆ–‡ไปถ๏ผš่ฟ™ไธชๆ–‡ไปถๆฏ”่พƒ้‡่ฆ๏ผŒๅฎƒๆ˜ฏๆ่ฟฐ่ฝฏไปถๅŒ…็š„ๅ็งฐ๏ผˆPackage๏ผ‰๏ผŒ็‰ˆๆœฌ๏ผˆVersion๏ผ‰๏ผŒๆ่ฟฐ๏ผˆDescription๏ผ‰็ญ‰๏ผŒๆ˜ฏdebๅŒ…ๅฟ…้กปๅ‰งๆœฌ็š„ๆ่ฟฐๆ€งๆ–‡ไปถ๏ผŒไปฅไพฟไบŽ่ฝฏไปถ็š„ๅฎ‰่ฃ…็ฎก็†ๅ’Œ็ดขๅผ•ใ€‚ ๅ…ถไธญๅฏ่ƒฝไผšๆœ‰ไธ‹้ข็š„ๅญ—ๆฎต๏ผš -- Package ๅŒ…ๅ -- Version ็‰ˆๆœฌ -- Architecture๏ผš่ฝฏไปถๅŒ…็ป“ๆž„๏ผŒๅฆ‚ๅŸบไบŽi386, amd64,m68k, sparc, alpha, powerpc็ญ‰ -- Priority๏ผš็”ณๆ˜Ž่ฝฏไปถๅฏนไบŽ็ณป็ปŸ็š„้‡่ฆ็จ‹ๅบฆ๏ผŒๅฆ‚required, standard, optional, extra็ญ‰ -- Essential๏ผš็”ณๆ˜Žๆ˜ฏๅฆๆ˜ฏ็ณป็ปŸๆœ€ๅŸบๆœฌ็š„่ฝฏไปถๅŒ…๏ผˆ้€‰้กนไธบyes/no๏ผ‰๏ผŒๅฆ‚ๆžœๆ˜ฏ็š„่ฏ๏ผŒ่ฟ™ๅฐฑ่กจๆ˜Ž่ฏฅ่ฝฏไปถๆ˜ฏ็ปดๆŒ็ณป็ปŸ็จณๅฎšๅ’Œๆญฃๅธธ่ฟ่กŒ็š„่ฝฏไปถๅŒ…๏ผŒไธๅ…่ฎธไปปไฝ•ๅฝขๅผ็š„ๅธ่ฝฝ๏ผˆ้™ค้ž่ฟ›่กŒๅผบๅˆถๆ€ง็š„ๅธ่ฝฝ๏ผ‰ -- Section๏ผš็”ณๆ˜Ž่ฝฏไปถ็š„็ฑปๅˆซ๏ผŒๅธธ่ง็š„ๆœ‰utils, net, mail, text, devel ็ญ‰ -- Depends๏ผš่ฝฏไปถๆ‰€ไพ่ต–็š„ๅ…ถไป–่ฝฏไปถๅŒ…ๅ’Œๅบ“ๆ–‡ไปถใ€‚ๅฆ‚ๆžœๆ˜ฏไพ่ต–ๅคšไธช่ฝฏไปถๅŒ…ๅ’Œๅบ“ๆ–‡ไปถ๏ผŒๅฝผๆญคไน‹้—ด้‡‡็”จ้€—ๅท้š”ๅผ€ -- Pre-Depends๏ผš่ฝฏไปถๅฎ‰่ฃ…ๅ‰ๅฟ…้กปๅฎ‰่ฃ…ใ€้…็ฝฎไพ่ต–ๆ€ง็š„่ฝฏไปถๅŒ…ๅ’Œๅบ“ๆ–‡ไปถ๏ผŒๅฎƒๅธธๅธธ็”จไบŽๅฟ…้กป็š„้ข„่ฟ่กŒ่„šๆœฌ้œ€ๆฑ‚ -- Recommends๏ผš่ฟ™ไธชๅญ—ๆฎต่กจๆ˜ŽๆŽจ่็š„ๅฎ‰่ฃ…็š„ๅ…ถไป–่ฝฏไปถๅŒ…ๅ’Œๅบ“ๆ–‡ไปถ -- Suggests๏ผšๅปบ่ฎฎๅฎ‰่ฃ…็š„ๅ…ถไป–่ฝฏไปถๅŒ…ๅ’Œๅบ“ๆ–‡ไปถ -- Description๏ผšๅฏนๅŒ…็š„ๆ่ฟฐ -- Installed-Size๏ผšๅฎ‰่ฃ…็š„ๅŒ…ๅคงๅฐ -- Maintainer๏ผšๅŒ…็š„ๅˆถไฝœ่€…๏ผŒ่”็ณปๆ–นๅผ็ญ‰ ๆˆ‘็š„ๆต‹่ฏ•ๅŒ…็š„control๏ผš

Package: kellan-test Version: 1.0 Architecture: all Maintainer: Kellan Fan Installed-Size: 128 Recommends: Suggests: Section: devel Priority: optional Multi-Arch: foreign Description: just for test ไธ‰ ๅˆถไฝœๅŒ… ๅˆถไฝœๅŒ…ๅ…ถๅฎžๅพˆ็ฎ€ๅ•๏ผŒๅฐฑไธ€ๆกๅ‘ฝไปค dpkg -b <ๅŒ…็›ฎๅฝ•> <ๅŒ…ๅ็งฐ>.deb

ๅ›› ๅ…ถไป–ๅ‘ฝไปค ๅฎ‰่ฃ… dpkg -i xxx.deb ๅธ่ฝฝ dpkg -r xxx.deb ่งฃๅŽ‹็ผฉๅŒ… dpkg -X xxx.deb [dirname]

$ dpkg -b /Users/mac/Desktop/debPath debName.deb
dpkg-deb: ๆญฃๅœจ 'x.deb' ไธญๆž„ๅปบ่ฝฏไปถๅŒ… 'com.gtx.gtx'ใ€‚
#import <UIKit/UIKit.h>
#import <objc/runtime.h>

#define kBundlePath @"/Library/Application Support/Neptune"

BOOL isFluidInterfaceEnabled;
long _homeButtonType = 1;
BOOL isHomeIndicatorEnabled;
BOOL isButtonCombinationOverrideDisabled;
BOOL isTallKeyboardEnabled;
BOOL isPIPEnabled;
int  statusBarStyle;
BOOL isWalletEnabled;
BOOL isNewsIconEnabled;
BOOL prototypingEnabled = NO;

@interface CALayer (CornerAddition)
-(bool)continuousCorners;
@property (assign) bool continuousCorners;
-(void)setContinuousCorners:(bool)arg1;
@end

/// MARK: - Group: Button remap
%group ButtonRemap

// Siri remap
%hook SBLockHardwareButtonActions
- (id)initWithHomeButtonType:(long long)arg1 proximitySensorManager:(id)arg2 {
    return %orig(_homeButtonType, arg2);
}
%end

%hook SBHomeHardwareButtonActions
- (id)initWitHomeButtonType:(long long)arg1 {
    return %orig(_homeButtonType);
}
%end

// Screenshot remap
int applicationDidFinishLaunching;

%hook SpringBoard
-(void)applicationDidFinishLaunching:(id)application {
    applicationDidFinishLaunching = 2;
    %orig;
}
%end

%hook SBPressGestureRecognizer
- (void)setAllowedPressTypes:(NSArray *)arg1 {
    NSArray * lockHome = @[@104, @101];
    NSArray * lockVol = @[@104, @102, @103];
    if ([arg1 isEqual:lockVol] && applicationDidFinishLaunching == 2) {
        %orig(lockHome);
        applicationDidFinishLaunching--;
        return;
    }
    %orig;
}
%end

%hook SBClickGestureRecognizer
- (void)addShortcutWithPressTypes:(id)arg1 {
    if (applicationDidFinishLaunching == 1) {
        applicationDidFinishLaunching--;
        return;
    }
    %orig;
}
%end

%hook SBHomeHardwareButton
- (id)initWithScreenshotGestureRecognizer:(id)arg1 homeButtonType:(long long)arg2 buttonActions:(id)arg3 gestureRecognizerConfiguration:(id)arg4 {
    return %orig(arg1,_homeButtonType,arg3,arg4);
}
- (id)initWithScreenshotGestureRecognizer:(id)arg1 homeButtonType:(long long)arg2 {
    return %orig(arg1,_homeButtonType);
}
%end

%hook SBLockHardwareButton
- (id)initWithScreenshotGestureRecognizer:(id)arg1 shutdownGestureRecognizer:(id)arg2 proximitySensorManager:(id)arg3 homeHardwareButton:(id)arg4 volumeHardwareButton:(id)arg5 buttonActions:(id)arg6 homeButtonType:(long long)arg7 createGestures:(_Bool)arg8 {
    return %orig(arg1,arg2,arg3,arg4,arg5,arg6,_homeButtonType,arg8);
}
- (id)initWithScreenshotGestureRecognizer:(id)arg1 shutdownGestureRecognizer:(id)arg2 proximitySensorManager:(id)arg3 homeHardwareButton:(id)arg4 volumeHardwareButton:(id)arg5 homeButtonType:(long long)arg6 {
    return %orig(arg1,arg2,arg3,arg4,arg5,_homeButtonType);
}
%end

%hook SBVolumeHardwareButton
- (id)initWithScreenshotGestureRecognizer:(id)arg1 shutdownGestureRecognizer:(id)arg2 homeButtonType:(long long)arg3 {
    return %orig(arg1,arg2,_homeButtonType);
}
%end

%end

%group ControlCenter122UI

// MARK: Control Center media controls transition (from iOS 12.2 beta)
@interface MediaControlsRoutingButtonView : UIView
- (long long)currentMode;
@end

long currentCachedMode = 99;

static CALayer* playbackIcon;
static CALayer* AirPlayIcon;
static CALayer* platterLayer;

%hook MediaControlsRoutingButtonView
- (void)_updateGlyph {

    if (self.currentMode == currentCachedMode) { return; }

    currentCachedMode = self.currentMode;

    if (self.layer.sublayers.count >= 1) {
        if (self.layer.sublayers[0].sublayers.count >= 1) {
            if (self.layer.sublayers[0].sublayers[0].sublayers.count == 2) {

                playbackIcon = self.layer.sublayers[0].sublayers[0].sublayers[1].sublayers[0];
                AirPlayIcon = self.layer.sublayers[0].sublayers[0].sublayers[1].sublayers[1];
                platterLayer = self.layer.sublayers[0].sublayers[0].sublayers[1];

                if (self.currentMode == 2) { // Play/Pause Mode

                    // Play/Pause Icon
                    playbackIcon.speed = 0.5;

                    UIViewPropertyAnimator *animator = [[UIViewPropertyAnimator alloc] initWithDuration:1 dampingRatio:1 animations:^{
                        playbackIcon.transform = CATransform3DMakeScale(-1, -1, 1);
                        playbackIcon.opacity = 0.75;
                    }];
                    [animator startAnimation];

                    // AirPlay Icon
                    AirPlayIcon.speed = 0.75;

                    UIViewPropertyAnimator *animator2 = [[UIViewPropertyAnimator alloc] initWithDuration:1 dampingRatio:1 animations:^{
                        AirPlayIcon.transform = CATransform3DMakeScale(0.85, 0.85, 1);
                        AirPlayIcon.opacity = -0.75;
                    }];
                    [animator2 startAnimation];

                    platterLayer.backgroundColor = [[UIColor colorWithRed:0 green:0.478 blue:1.0 alpha:0.0] CGColor];

                } else if (self.currentMode == 0 || self.currentMode == 1) { // AirPlay Mode

                    // Play/Pause Icon
                    playbackIcon.speed = 0.75;

                    UIViewPropertyAnimator *animator = [[UIViewPropertyAnimator alloc] initWithDuration:1 dampingRatio:1 animations:^{
                        playbackIcon.transform = CATransform3DMakeScale(-0.85, -0.85, 1);
                        playbackIcon.opacity = -0.75;
                    }];
                    [animator startAnimation];

                    // AirPlay Icon
                    AirPlayIcon.speed = 0.5;

                    UIViewPropertyAnimator *animator2 = [[UIViewPropertyAnimator alloc] initWithDuration:1 dampingRatio:1 animations:^{
                        AirPlayIcon.transform = CATransform3DMakeScale(1, 1, 1);
                        if (self.currentMode == 0) {
                            AirPlayIcon.opacity = 0.75;
                            platterLayer.backgroundColor = [[UIColor colorWithRed:0 green:0.478 blue:1.0 alpha:0.0] CGColor];
                        } else if (self.currentMode == 1) {
                            AirPlayIcon.opacity = 1;
                            platterLayer.backgroundColor = [[UIColor colorWithRed:0 green:0.478 blue:1.0 alpha:1.0] CGColor];
                            platterLayer.cornerRadius = 18;
                        }
                    }];
                    [animator2 startAnimation];
                }
            }
        }
    }
}
%end

%end

%group SBButtonRefinements

// MARK: App icon selection override

long _iconHighlightInitiationSkipper = 0;

@interface SBIconView : UIView
- (void)setHighlighted:(bool)arg1;
@property(nonatomic, getter=isHighlighted) _Bool highlighted;
@end

%hook SBIconView
- (void)setHighlighted:(bool)arg1 {

    if (_iconHighlightInitiationSkipper) {
        %orig;
        return;
    }

    if (arg1 == YES) {

        if (!self.highlighted) {
            _iconHighlightInitiationSkipper = 1;
            %orig;
            %orig(NO);
            _iconHighlightInitiationSkipper = 0;
        }

        UIViewPropertyAnimator *animator = [[UIViewPropertyAnimator alloc] initWithDuration:0.125 dampingRatio:1 animations:^{
            %orig;
        }];
        [animator startAnimation];
    } else {
        UIViewPropertyAnimator *animator = [[UIViewPropertyAnimator alloc] initWithDuration:0.3 dampingRatio:1 animations:^{
            %orig;
        }];
        [animator startAnimation];
    }
    return;
}
%end

@interface NCToggleControl : UIView
- (void)setHighlighted:(bool)arg1;
@end

%hook NCToggleControl
- (void)setHighlighted:(bool)arg1 {
    if (arg1 == YES) {

        UIViewPropertyAnimator *animator = [[UIViewPropertyAnimator alloc] initWithDuration:0.125 curve:UIViewAnimationCurveEaseOut animations:^{
            %orig;
        }];
        [animator startAnimation];
    } else {
        UIViewPropertyAnimator *animator = [[UIViewPropertyAnimator alloc] initWithDuration:0.5 dampingRatio:1 animations:^{
            %orig;
        }];
        [animator startAnimation];
    }
    return;
}
%end


@interface SBEditingDoneButton : UIView
- (void)setHighlighted:(bool)arg1;
@end

%hook SBEditingDoneButton
-(void)layoutSubviews {
    %orig;

    if (!self.layer.masksToBounds) {
        self.layer.continuousCorners = YES;
        self.layer.masksToBounds = YES;
        self.layer.cornerRadius = 13;
    }

    /*
     CGRect _frame = self.frame;

     if (_frame.origin.y != 16) {
     _frame.origin.y = 16;
     self.frame = _frame;
     }*/
}
- (void)setHighlighted:(bool)arg1 {
    if (arg1 == YES) {

        UIViewPropertyAnimator *animator = [[UIViewPropertyAnimator alloc] initWithDuration:0.1 curve:UIViewAnimationCurveEaseOut animations:^{
            %orig;
        }];
        [animator startAnimation];
    } else {
        UIViewPropertyAnimator *animator = [[UIViewPropertyAnimator alloc] initWithDuration:0.5 dampingRatio:1 animations:^{
            %orig;
        }];
        [animator startAnimation];
    }
    return;
}
%end

@interface SBFolderIconBackgroundView : UIView
@end

%hook SBFolderIconBackgroundView
- (void)layoutSubviews {
    %orig;
    self.layer.continuousCorners = YES;
}
%end
/*
 @interface SBFolderIconImageView : UIView
 @end

 %hook SBFolderIconImageView
 - (void)layoutSubviews {
 if (!self.layer.masksToBounds) {
 self.layer.continuousCorners = YES;
 self.layer.masksToBounds = YES;
 self.layer.cornerRadius = 13.5;
 }
 return %orig;
 }
 %end
 */

// MARK: Widgets screen button highlight
@interface WGShortLookStyleButton : UIView
- (void)setHighlighted:(bool)arg1;
@end

%hook WGShortLookStyleButton
- (void)setHighlighted:(bool)arg1 {
    if (arg1 == YES) {

        UIViewPropertyAnimator *animator = [[UIViewPropertyAnimator alloc] initWithDuration:0.25 dampingRatio:1 animations:^{
            self.alpha = 0.6;
        }];
        [animator startAnimation];
    } else {
        UIViewPropertyAnimator *animator = [[UIViewPropertyAnimator alloc] initWithDuration:0.6 dampingRatio:1 animations:^{
            self.alpha = 1;
        }];
        [animator startAnimation];
    }
    return;
}
%end

%end

/// MARK: - Group: Springboard modifications
%group FluidInterface

// MARK: Enable fluid switcher
%hook BSPlatform
- (NSInteger)homeButtonType {
    return 2;
}
%end

// MARK: Lock screen quick action toggle implementation

// Define custom springboard method to remove all subviews.
@interface UIView (SpringBoardAdditions)
- (void)sb_removeAllSubviews;
@end

@interface SBDashBoardQuickActionsView : UIView
@end

// Reinitialize quick action toggles
%hook SBDashBoardQuickActionsView
- (void)_layoutQuickActionButtons {

    %orig;
    for (UIView *subview in self.subviews) {
        if (subview.frame.size.width < 50) {
            if (subview.frame.origin.x < 50) {
                CGRect _frame = subview.frame;
                _frame = CGRectMake(46, _frame.origin.y - 90, 50, 50);
                subview.frame = _frame;
                [subview sb_removeAllSubviews];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-value"
                [subview init];
#pragma clang diagnostic pop
            } else if (subview.frame.origin.x > 100) {
                CGFloat _screenWidth = subview.frame.origin.x + subview.frame.size.width / 2;
                CGRect _frame = subview.frame;
                _frame = CGRectMake(_screenWidth - 96, _frame.origin.y - 90, 50, 50);
                subview.frame = _frame;
                [subview sb_removeAllSubviews];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-value"
                [subview init];
#pragma clang diagnostic pop
            }
        }
    }
}
%end

// MARK: Cover sheet control centre grabber initialization
typedef enum {
    Tall=0,
    Regular=1
} NEPStatusBarHeightStyle;

NEPStatusBarHeightStyle _statusBarHeightStyle = Tall;

@interface SBDashBoardTeachableMomentsContainerView : UIView
@property(retain, nonatomic) UIView *controlCenterGrabberView;
@property(retain, nonatomic) UIView *controlCenterGrabberEffectContainerView;
@end

%hook SBDashBoardTeachableMomentsContainerView
- (void)layoutSubviews {
    %orig;

    if (_statusBarHeightStyle == Tall) {
        self.controlCenterGrabberEffectContainerView.frame = CGRectMake(self.frame.size.width - 73,36,46,2.5);
        self.controlCenterGrabberView.frame = CGRectMake(0,0,46,2.5);
    } else if (@available(iOS 12.1, *)) {
        // Rounded status bar visual provider
        self.controlCenterGrabberEffectContainerView.frame = CGRectMake(self.frame.size.width - 85.5,26,60.5,2.5);
        self.controlCenterGrabberView.frame = CGRectMake(0,0,60.5,2.5);
    } else {
        // Non-rounded status bar visual provider
        self.controlCenterGrabberEffectContainerView.frame = CGRectMake(self.frame.size.width - 75.5,24,60.5,2.5);
        self.controlCenterGrabberView.frame = CGRectMake(0,0,60.5,2.5);
    }
}
%end

// MARK: Corner radius implementation
@interface _UIRootWindow : UIView
@property (setter=_setContinuousCornerRadius:, nonatomic) double _continuousCornerRadius;
- (double)_continuousCornerRadius;
- (void)_setContinuousCornerRadius:(double)arg1;
@end

// Implement system wide continuousCorners.
%hook _UIRootWindow
- (void)layoutSubviews {
    %orig;
    self._continuousCornerRadius = 5;
    self.clipsToBounds = YES;
    return;
}
%end

// Implement corner radius adjustment for when in the app switcher scroll view.
/*%hook SBDeckSwitcherPersonality
- (double)_cardCornerRadiusInAppSwitcher {
    return 17.5;
}
%end*/

// Implement round screenshot preview edge insets.
%hook UITraitCollection
+ (id)traitCollectionWithDisplayCornerRadius:(CGFloat)arg1 {
    return %orig(17);
}
%end

@interface SBAppSwitcherPageView : UIView
@property(nonatomic, assign) double cornerRadius;
@property(nonatomic) _Bool blocksTouches;
- (void)_updateCornerRadius;
@end

BOOL blockerPropagatedEvent = false;
double currentCachedCornerRadius = 0;

/// IMPORTANT: DO NOT MESS WITH THIS LOGIC. EVERYTHING HERE IS DONE FOR A REASON.

// Override rendered corner radius in app switcher page, (for anytime the fluid switcher gestures are running).
%hook SBAppSwitcherPageView

-(void)setBlocksTouches:(BOOL)arg1 {
    if (!arg1 && (self.cornerRadius == 17 || self.cornerRadius == 5 || self.cornerRadius == 3.5)) {
        blockerPropagatedEvent = true;
        self.cornerRadius = 5;
        [self _updateCornerRadius];
        blockerPropagatedEvent = false;
    } else if (self.cornerRadius == 17 || self.cornerRadius == 5 || self.cornerRadius == 3.5) {
        blockerPropagatedEvent = true;
        self.cornerRadius = 17;
        [self _updateCornerRadius];
        blockerPropagatedEvent = false;
    }

    %orig(arg1);
}

- (void)setCornerRadius:(CGFloat)arg1 {

    currentCachedCornerRadius = MSHookIvar<double>(self, "_cornerRadius");

    CGFloat arg1_overwrite = arg1;

    if ((arg1 != 17 || arg1 != 5 || arg1 != 0) && self.blocksTouches) {
        return %orig(arg1);
    }

    if (blockerPropagatedEvent && arg1 != 17) {
        return %orig(arg1);
    }

    if (arg1 == 0 && !self.blocksTouches) {
        %orig(0);
        return;
    }

    if (self.blocksTouches) {
        arg1_overwrite = 17;
    } else if (arg1 == 17) {
        // THIS IS THE ONLY BLOCK YOU CAN CHANGE
        arg1_overwrite = 5;
        // Todo: detect when, in this case, the app is being pulled up from the bottom, and activate the rounded corners.
    }

    UIView* _overlayClippingView = MSHookIvar<UIView*>(self, "_overlayClippingView");
    if (!_overlayClippingView.layer.allowsEdgeAntialiasing) {
        _overlayClippingView.layer.allowsEdgeAntialiasing = true;
    }

    %orig(arg1_overwrite);
}

- (void)_updateCornerRadius {
    /// CAREFUL HERE, WATCH OUT FOR THE ICON MORPH ANIMATION ON APPLICATION LAUNCH
    if ((self.cornerRadius == 5 && currentCachedCornerRadius == 17.0)) {
        UIViewPropertyAnimator *animator = [[UIViewPropertyAnimator alloc] initWithDuration:0.35 dampingRatio:1 animations:^{
            %orig;
        }];
        [animator startAnimation];
    } else {
        %orig;
    }
}
%end

// Override Reachability corner radius.
%hook SBReachabilityBackgroundView
- (double)_displayCornerRadius {
    return 5;
}
%end


// MARK: Reachability settings override
%hook SBReachabilitySettings
- (void)setSystemWideSwipeDownHeight:(double) systemWideSwipeDownHeight {
    return %orig(100);
}
%end

// High Resolution Wallpaper
@interface SBFStaticWallpaperImageView : UIImageView
@end

%hook SBFStaticWallpaperImageView
- (void)setImage:(id)arg1 {

    if (!prototypingEnabled) {
        return %orig;
    }

    NSBundle *bundle = [[NSBundle alloc] initWithPath:kBundlePath];
    NSString *imagePath = [bundle pathForResource:@"DoubleBubble_Red" ofType:@"png"];
    UIImage *myImage = [UIImage imageWithContentsOfFile:imagePath];

    UIImage *originalDownscaledImage = arg1;

    if (originalDownscaledImage.size.width == 375) {
        return %orig(myImage);
    }

    return %orig(arg1);
}
%end

%end


%group KeyboardDock

%hook UIRemoteKeyboardWindowHosted
- (UIEdgeInsets)safeAreaInsets {
    UIEdgeInsets orig = %orig;
    orig.bottom = 44;
    return orig;
}
%end

%hook UIKeyboardImpl
+(UIEdgeInsets)deviceSpecificPaddingForInterfaceOrientation:(NSInteger)orientation inputMode:(id)mode {
    UIEdgeInsets orig = %orig;
    orig.bottom = 44;
    return orig;
}

%end

@interface UIKeyboardDockView : UIView
@end

%hook UIKeyboardDockView

- (CGRect)bounds {
    CGRect bounds = %orig;
    if (bounds.origin.y == 0) {
        bounds.origin.y -=13;
    }
    return bounds;
}

- (void)layoutSubviews {
    %orig;
}

%end

%hook UIInputWindowController
- (UIEdgeInsets)_viewSafeAreaInsetsFromScene {
    return UIEdgeInsetsMake(0,0,44,0);
}
%end

%end

int _controlCenterStatusBarInset = -10;

// MARK: - Group: Springboard modifications (Control Center Status Bar inset)
%group ControlCenterModificationsStatusBar

@interface CCUIHeaderPocketView : UIView
@end

%hook CCUIHeaderPocketView
- (void)layoutSubviews {
    %orig;

    CGRect _frame = self.frame;
    _frame.origin.y = _controlCenterStatusBarInset;
    self.frame = _frame;
}
%end

%end

%group StatusBarProvider

// MARK: - Variable modern status bar implementation

%hook _UIStatusBarVisualProvider_iOS
+ (Class)class {
    if (statusBarStyle == 0) {
        return NSClassFromString(@"_UIStatusBarVisualProvider_Split58");
    } else if (@available(iOS 12.1, *)) {
        return NSClassFromString(@"_UIStatusBarVisualProvider_RoundedPad_ForcedCellular");
    }
    return NSClassFromString(@"_UIStatusBarVisualProvider_Pad_ForcedCellular");
}
%end

%hook _UIStatusBar
+ (double)heightForOrientation:(long long)arg1 {
    if (arg1 == 1 || arg1 == 2) {
        if (statusBarStyle == 0) {
            return %orig - 10;
        } else if (statusBarStyle == 1) {
            return %orig - 4;
        }
    }
    return %orig;
}
%end

%end


%group StatusBarModern

%hook UIStatusBarWindow
+ (void)setStatusBar:(Class)arg1 {
    return %orig(NSClassFromString(@"UIStatusBar_Modern"));
}
%end

%hook UIStatusBar_Base
+ (Class)_implementationClass {
    return NSClassFromString(@"UIStatusBar_Modern");
}
+ (void)_setImplementationClass:(Class)arg1 {
    return %orig(NSClassFromString(@"UIStatusBar_Modern"));
}
%end

%hook _UIStatusBarData
- (void)setBackNavigationEntry:(id)arg1 {
    return;
}
%end

%end


float _bottomInset = 21;

%group TabBarSizing

// MARK: - Inset behavior modifications
%hook UITabBar

- (void)layoutSubviews {
    %orig;
    CGRect _frame = self.frame;
    if (_frame.size.height == 49) {
        _frame.size.height = 70;
        _frame.origin.y = [[UIScreen mainScreen] bounds].size.height - 70;
    }
    self.frame = _frame;
}

%end

%hook UIApplicationSceneSettings

- (UIEdgeInsets)safeAreaInsetsLandscapeLeft {
    UIEdgeInsets _insets = %orig;
    _insets.bottom = _bottomInset;
    return _insets;
}
- (UIEdgeInsets)safeAreaInsetsLandscapeRight {
    UIEdgeInsets _insets = %orig;
    _insets.bottom = _bottomInset;
    return _insets;
}
- (UIEdgeInsets)safeAreaInsetsPortrait {
    UIEdgeInsets _insets = %orig;
    _insets.bottom = _bottomInset;
    return _insets;
}
- (UIEdgeInsets)safeAreaInsetsPortraitUpsideDown {
    UIEdgeInsets _insets = %orig;
    _insets.bottom = _bottomInset;
    return _insets;
}

%end

%end

// MARK: - Toolbar resizing implementation
%group ToolbarSizing
/*
 @interface UIToolbar (modification)
 @property (setter=_setBackgroundView:, nonatomic, retain) UIView *_backgroundView;
 @end

 %hook UIToolbar

 - (void)layoutSubviews {
 %orig;
 CGRect _frame = self.frame;
 if (_frame.size.height == 44) {
 _frame.origin.y = [[UIScreen mainScreen] bounds].size.height - 54;
 }
 self.frame = _frame;

 _frame = self._backgroundView.frame;
 _frame.size.height = 54;
 self._backgroundView.frame = _frame;
 }

 %end
 */
%end

%group HideLuma

// Hide Home Indicator
%hook UIViewController
- (BOOL)prefersHomeIndicatorAutoHidden {
    return YES;
}
%end

%end

%group CompletelyHideLuma

// Hide HomeBar
@interface MTLumaDodgePillView : UIView
@end

%hook MTLumaDodgePillView
- (id)initWithFrame:(struct CGRect)arg1 {
      return NULL;
}
%end

%end

// MARK: - Shortcuts
%group Shortcuts

@interface WFFloatingLayer : CALayer
@end

%hook WFFloatingLayer
-(BOOL)continuousCorners {
    return YES;
}
%end

%end

// MARK: - Twitter
%group Twitter

@interface TFNCustomTabBar : UIView
@end

%hook TFNCustomTabBar

- (void)layoutSubviews {
    %orig;
    CGRect _frame = self.frame;
    if (_frame.origin.y != [[UIScreen mainScreen] bounds].size.height - _frame.size.height) {
        _frame.origin.y -= 3.5;
    }
    self.frame = _frame;
}

%end

%end

// MARK: - Calendar
%group Calendar

@interface CompactMonthDividedListSwitchButton : UIView
@end

%hook CompactMonthDividedListSwitchButton
- (void)layoutSubviews {
    %orig;

    self.layer.cornerRadius = 3;
    self.layer.continuousCorners = YES;
    self.clipsToBounds = YES;
}
%end;

%end

// MARK: - Picture in Picture
%group PIPOverride

// Override MobileGestalt to always return true for PIP key - Acknowledgements: Andrew Wiik (LittleX)
extern "C" Boolean MGGetBoolAnswer(CFStringRef);
%hookf(Boolean, MGGetBoolAnswer, CFStringRef key) {
#define k(key_) CFEqual(key, CFSTR(key_))
    if (k("nVh/gwNpy7Jv1NOk00CMrw"))
        return YES;
    return %orig;
}

%end

@interface _UITableViewCellSeparatorView : UIView
- (id)_viewControllerForAncestor;
@end

@interface UITableViewHeaderFooterView (WalletAdditions)
- (id)_viewControllerForAncestor;
@end

@interface UITableViewCell (WalletAdditions)
- (id)_viewControllerForAncestor;
@end

@interface UISegmentedControl (WalletAdditions)
@property (nonatomic, retain) UIColor *tintColor;
- (id)_viewControllerForAncestor;
@end

@interface UITextView (WalletAdditions)
- (id)_viewControllerForAncestor;
@end

@interface PKContinuousButton : UIView
@end



%group NEPThemeEngine

@interface SBApplicationIcon : NSObject
@end

%hook SBApplicationIcon
- (id)getCachedIconImage:(int)arg1 {

    NSString *_applicationBundleID = MSHookIvar<NSString*>(self, "_applicationBundleID");

    if (/*[_applicationBundleID isEqualToString:@"com.atebits.Tweetie2"] || */[_applicationBundleID isEqualToString:@"com.apple.news"]) {

        NSBundle *bundle = [[NSBundle alloc] initWithPath:kBundlePath];
        NSString *imagePath = [bundle pathForResource:_applicationBundleID ofType:@"png"];
        UIImage *myImage = [UIImage imageWithContentsOfFile:imagePath];

        return myImage;
    }
    return %orig;
}
- (id)getUnmaskedIconImage:(int)arg1 {

    NSString *_applicationBundleID = MSHookIvar<NSString*>(self, "_applicationBundleID");

    if (/*[_applicationBundleID isEqualToString:@"com.atebits.Tweetie2"] || */[_applicationBundleID isEqualToString:@"com.apple.news"]) {

        NSBundle *bundle = [[NSBundle alloc] initWithPath:kBundlePath];
        NSString *imagePath = [bundle pathForResource:[NSString stringWithFormat:@"%@_unmasked", _applicationBundleID] ofType:@"png"];
        UIImage *myImage = [UIImage imageWithContentsOfFile:imagePath];

        return myImage;
    }
    return %orig;
}
- (id)generateIconImage:(int)arg1 {

    NSString *_applicationBundleID = MSHookIvar<NSString*>(self, "_applicationBundleID");

    if (/*[_applicationBundleID isEqualToString:@"com.atebits.Tweetie2"] || */[_applicationBundleID isEqualToString:@"com.apple.news"]) {

        NSBundle *bundle = [[NSBundle alloc] initWithPath:kBundlePath];
        NSString *imagePath = [bundle pathForResource:_applicationBundleID ofType:@"png"];
        UIImage *myImage = [UIImage imageWithContentsOfFile:imagePath];

        return myImage;
    }
    return %orig;
}
%end

%end

// MARK: - Wallet
%group Wallet122UI

%hook _UITableViewCellSeparatorView
- (void)layoutSubviews {
    if ([[NSString stringWithFormat:@"%@", self._viewControllerForAncestor] containsString:@"PassDetailViewController"] || [[NSString stringWithFormat:@"%@", self._viewControllerForAncestor] containsString:@"PKPaymentPreferencesViewController"]) {
        if (self.frame.origin.x == 0) {
            self.hidden = YES;
        }
    }
}
%end

%hook UISegmentedControl
- (void)layoutSubviews {
    %orig;
    if ([[NSString stringWithFormat:@"%@", self._viewControllerForAncestor] containsString:@"PassDetailViewController"]) {
        self.tintColor = [UIColor blackColor];
    }
}
%end

%hook UITextView
- (void)layoutSubviews {
    %orig;
    CGRect _frame = self.frame;
    if ([[NSString stringWithFormat:@"%@", self._viewControllerForAncestor] containsString:@"PKBarcodePassDetailViewController"] && _frame.origin.x == 16) {
        _frame.origin.x += 10;
        self.frame = _frame;
    }
}
%end



%hook PKContinuousButton
- (void)updateTitleColorWithColor:(id)arg1 {
    //if (self.frame.size.width < 90) {
    //%orig([UIColor blackColor]);
    //} else {
    %orig;
    //}
}
%end

%hook UITableViewCell
- (void)layoutSubviews {
    %orig;
    if ([[NSString stringWithFormat:@"%@", self._viewControllerForAncestor] containsString:@"PassDetailViewController"] || [[NSString stringWithFormat:@"%@", self._viewControllerForAncestor] containsString:@"PKPaymentPreferencesViewController"]) {
        CGRect _frame = self.frame;
        if (_frame.origin.x == 0) {

            self.layer.cornerRadius = 10;
            self.clipsToBounds = YES;

            typedef enum {
                Lone=0,
                Bottom=1,
                Top=2,
                Middle=3
            } NEPCellPosition;

            NEPCellPosition _cellPosition = Middle;

            for (UIView *subview in self.subviews) {
                if ([[NSString stringWithFormat:@"%@", subview] containsString:@"_UITableViewCellSeparatorView"] && subview.frame.origin.x == 0 && subview.frame.origin.y == 0 && subview.frame.size.height == 0.5) {
                    _cellPosition = Top;
                }
            }

            for (UIView *subview in self.subviews) {
                if ([[NSString stringWithFormat:@"%@", subview] containsString:@"_UITableViewCellSeparatorView"] && subview.frame.origin.x == 0 && subview.frame.origin.y > 0 && subview.frame.size.height == 0.5) {
                    if (_cellPosition == Top) {
                        _cellPosition = Lone;
                    } else {
                        _cellPosition = Bottom;
                    }
                }
            }

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
            if (_cellPosition == Top) {
                self.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner;
            } else if (_cellPosition == Bottom) {
                self.layer.maskedCorners = kCALayerMinXMaxYCorner | kCALayerMaxXMaxYCorner;
            } else if (_cellPosition == Middle) {
                self.layer.cornerRadius = 0;
                self.clipsToBounds = NO;
            }
#pragma clang diagnostic pop

            _frame.size.width -= 32;
            _frame.origin.x = 16;
            self.frame = _frame;
        }
    }
}
%end

%hook UITableViewHeaderFooterView
- (void)layoutSubviews {
    if ([[NSString stringWithFormat:@"%@", self._viewControllerForAncestor] containsString:@"PassDetailViewController"]) {
        if (self.frame.origin.x == 0) {
            CGRect _frame = self.frame;
            //if (_frame.size.width > 200) {
            _frame.size.width -= 10;
            //}
            _frame.origin.x += 5;
            self.frame = _frame;
        }
    }
    %orig;
}
%end

%end

%group Maps

@interface MapsProgressButton : UIView
@end

%hook MapsProgressButton
- (void)layoutSubviews {
    %orig;
    self.layer.continuousCorners = true;
}
%end

%end

%group Castro

@interface SUPTabsCardViewController : UIViewController
@end

%hook SUPTabsCardViewController
- (void)viewDidLoad {
    %orig;
    self.view.layer.mask = NULL;
    self.view.layer.continuousCorners = YES;
    self.view.layer.masksToBounds = YES;
    self.view.layer.cornerRadius = 10;
}
%end

@interface SUPDimExternalImageViewButton : UIView
- (void)setHighlighted:(bool)arg1;
@end

%hook SUPDimExternalImageViewButton
- (void)setHighlighted:(bool)arg1 {
    if (arg1 == YES) {

        UIViewPropertyAnimator *animator = [[UIViewPropertyAnimator alloc] initWithDuration:0.1 curve:UIViewAnimationCurveEaseOut animations:^{
            %orig;
        }];
        [animator startAnimation];
    } else {
        UIViewPropertyAnimator *animator = [[UIViewPropertyAnimator alloc] initWithDuration:0.4 dampingRatio:1 animations:^{
            %orig;
        }];
        [animator startAnimation];
    }
    return;
}
%end

%end

%ctor {

    NSString *bundleIdentifier = [NSBundle mainBundle].bundleIdentifier;

    // Gather current preference keys.
    NSString *settingsPath = @"/var/mobile/Library/Preferences/com.duraidabdul.neptune.plist";

    NSFileManager *fileManager = [NSFileManager defaultManager];

    NSMutableDictionary *currentSettings;

    BOOL shouldReadAndWriteDefaults = false;

    if ([fileManager fileExistsAtPath:settingsPath]){
        currentSettings = [[NSMutableDictionary alloc] initWithContentsOfFile:settingsPath];
        if ([[currentSettings objectForKey:@"preferencesVersionID"] intValue] != 100) {
          shouldReadAndWriteDefaults = true;
        }
    } else {
      shouldReadAndWriteDefaults = true;
    }

    if (shouldReadAndWriteDefaults) {
      NSBundle *bundle = [[NSBundle alloc] initWithPath:kBundlePath];
      NSString *defaultsPath = [bundle pathForResource:@"defaults" ofType:@"plist"];
      currentSettings = [[NSMutableDictionary alloc] initWithContentsOfFile:defaultsPath];

      [currentSettings writeToFile: settingsPath atomically:YES];
    }

    isFluidInterfaceEnabled = [[currentSettings objectForKey:@"isFluidInterfaceEnabled"] boolValue];
    isHomeIndicatorEnabled = [[currentSettings objectForKey:@"isHomeIndicatorEnabled"] boolValue];
    isButtonCombinationOverrideDisabled = [[currentSettings objectForKey:@"isButtonCombinationOverrideDisabled"] boolValue];
    isTallKeyboardEnabled = [[currentSettings objectForKey:@"isTallKeyboardEnabled"] boolValue];
    isPIPEnabled = [[currentSettings objectForKey:@"isPIPEnabled"] boolValue];
    statusBarStyle = [[currentSettings objectForKey:@"statusBarStyle"] intValue];
    isWalletEnabled = [[currentSettings objectForKey:@"isWalletEnabled"] boolValue];
    isNewsIconEnabled = [[currentSettings objectForKey:@"isNewsIconEnabled"] boolValue];
    prototypingEnabled = [[currentSettings objectForKey:@"prototypingEnabled"] boolValue];



    // Conditional status bar initialization
    NSArray *acceptedStatusBarIdentifiers = @[@"com.apple",
                                              @"com.culturedcode.ThingsiPhone",
                                              @"com.christianselig.Apollo",
                                              @"co.supertop.Castro-2",
                                              @"com.facebook.Messenger",
                                              @"com.saurik.Cydia",
                                              @"is.workflow.my.app"
                                              ];

    %init(StatusBarProvider);

    for (NSString *identifier in acceptedStatusBarIdentifiers) {
        if ((statusBarStyle == 0 && [bundleIdentifier containsString:identifier]) || statusBarStyle == 1) {
            %init(StatusBarModern);
        }
    }

    // Conditional inset adjustment initialization
    NSArray *acceptedInsetAdjustmentIdentifiers = @[@"com.apple",
                                                    @"com.culturedcode.ThingsiPhone",
                                                    @"com.christianselig.Apollo",
                                                    @"co.supertop.Castro-2",
                                                    @"com.chromanoir.Zeit",
                                                    @"com.chromanoir.spectre",
                                                    @"com.saurik.Cydia",
                                                    @"is.workflow.my.app"
                                                    ];
    NSArray *acceptedInsetAdjustmentIdentifiers_NoTabBarLabels = @[@"com.facebook.Facebook",
                                                                   @"com.facebook.Messenger",
                                                                   @"com.burbn.instagram",
                                                                   @"com.medium.reader",
                                                                   @"com.pcalc.mobile"
                                                                   ];

    BOOL isInsetAdjustmentEnabled = false;

    if (![bundleIdentifier containsString:@"mobilesafari"]) {
        for (NSString *identifier in acceptedInsetAdjustmentIdentifiers) {
            if ([bundleIdentifier containsString:identifier]) {
                isInsetAdjustmentEnabled = true;
                break;
            }
        }
        if (!isInsetAdjustmentEnabled) {
            for (NSString *identifier in acceptedInsetAdjustmentIdentifiers_NoTabBarLabels) {
                if ([bundleIdentifier containsString:identifier]) {
                    _bottomInset = 16;
                    isInsetAdjustmentEnabled = true;
                }
            }
        }
    }

    if (isHomeIndicatorEnabled && isFluidInterfaceEnabled) {
      if (isInsetAdjustmentEnabled) {
          %init(TabBarSizing);
          %init(ToolbarSizing);
      } else {
          %init(HideLuma);
      }
    } else {
      %init(CompletelyHideLuma);
    }

    // SpringBoard
    if ([bundleIdentifier isEqualToString:@"com.apple.springboard"]) {
        if (statusBarStyle != 0) {
            _statusBarHeightStyle = Regular;
            _controlCenterStatusBarInset = -24;
        }
        if (isFluidInterfaceEnabled) {
          %init(FluidInterface)
          %init(ButtonRemap)
        }

        %init(ControlCenter122UI)
        if (isFluidInterfaceEnabled) {
          %init(ControlCenterModificationsStatusBar)
        }
        %init(SBButtonRefinements)
    }

    // Wallet
    if ([bundleIdentifier containsString:@"Passbook"] && isWalletEnabled) {
        %init(Wallet122UI);
    }

    // Shortcuts
    if ([bundleIdentifier containsString:@"workflow"]) {
        %init(Shortcuts);
    }

    // Calendar
    if ([bundleIdentifier containsString:@"com.apple.mobilecal"]) {
        %init(Calendar);
    }

    // Maps
    if ([bundleIdentifier containsString:@"com.apple.Maps"]) {
        %init(Maps);
    }

    // Twitter
    if ([bundleIdentifier containsString:@"com.atebits.Tweetie2"] && prototypingEnabled) {
        %init(Twitter);
    }

    if ([bundleIdentifier containsString:@"supertop"]) {
        %init(Castro);
    }

    // Picture in picture
    if (isPIPEnabled) {
        %init(PIPOverride);
    }

    if (isNewsIconEnabled && [bundleIdentifier containsString:@"com.apple.springboard"]) {
        %init(NEPThemeEngine);
    }

    // Keyboard height adjustment
    if (isTallKeyboardEnabled) {
        %init(KeyboardDock);
    }

    // Any ungrouped hooks
    %init(_ungrouped);
}

Aspects Hookๆ˜ฏไป€ไนˆ?

Aspectsๆ˜ฏไธ€ไธชๅผ€ๆบ็š„็š„ๅบ“,้ขๅ‘ๅˆ‡้ข็ผ–็จ‹,ๅฎƒ่ƒฝๅ…่ฎธไฝ ๅœจๆฏไธ€ไธช็ฑปๅ’Œๆฏไธ€ไธชๅฎžไพ‹ไธญๅญ˜ๅœจ็š„ๆ–นๆณ•้‡Œ้ขๅŠ ๅ…ฅไปปไฝ•ไปฃ็ ใ€‚ๅฏไปฅๅœจๆ–นๆณ•ๆ‰ง่กŒไน‹ๅ‰ๆˆ–่€…ไน‹ๅŽๆ‰ง่กŒ,ไนŸๅฏไปฅๆ›ฟๆขๆŽ‰ๅŽŸๆœ‰็š„ๆ–นๆณ•ใ€‚้€š่ฟ‡Runtimeๆถˆๆฏ่ฝฌๅ‘ๅฎž็ŽฐHookใ€‚Aspectsไผš่‡ชๅŠจๅค„็†่ถ…็ฑป,ๆฏ”ๅธธ่ง„ๆ–นๆณ•่ฐƒ็”จๆ›ดๅฎนๆ˜“ไฝฟ็”จ,githubไธŠStarๅทฒ็ป่ถ…่ฟ‡6000ๅคš,ๅทฒ็ปๆฏ”่พƒ็จณๅฎšไบ†;

ๅ…ˆไปŽๆบ็ ๅ…ฅๆ‰‹,ๆœ€ๅŽๅ†่ฟ›่กŒๆ€ป็ป“,ๅฆ‚ๆžœๅฏนๆบ็ ไธๆ„Ÿๅ…ด่ถฃ็š„ๅฏไปฅ็›ดๆŽฅ่ทณๅˆฐๆ–‡็ซ ๆœซๅฐพๅŽปๆŸฅ็œ‹ๅ…ทไฝ“ๆต็จ‹

ไบŒ:Aspectsๆ˜ฏHookๅ‰็š„ๅ‡†ๅค‡ๅทฅไฝœ

  • (id)aspect_hookSelector:(SEL)selector withOptions:(AspectOptions)options usingBlock:(id)block error:(NSError **)error { return aspect_add((id)self, selector, options, block, error); }
  • (id)aspect_hookSelector:(SEL)selector withOptions:(AspectOptions)options usingBlock:(id)block error:(NSError **)error { return aspect_add(self, selector, options, block, error); } ้€š่ฟ‡ไธŠ้ข็š„ๆ–นๆณ•ๆทปๅŠ Hook,ไผ ๅ…ฅSEL(่ฆHook็š„ๆ–นๆณ•), options(่ฟœๆ–นๆณ•่ฐƒ็”จ่ฐƒ็”จไน‹ๅ‰ๆˆ–ไน‹ๅŽ่ฐƒ็”จๆˆ–่€…ๆ˜ฏๆ›ฟๆข),block(่ฆๆ‰ง่กŒ็š„ไปฃ็ ),error(้”™่ฏฏไฟกๆฏ)

static id aspect_add(id self, SEL selector, AspectOptions options, id block, NSError **error) { NSCParameterAssert(self); NSCParameterAssert(selector); NSCParameterAssert(block);

__block AspectIdentifier *identifier = nil;
aspect_performLocked(^{
    //ๅ…ˆๅˆคๆ–ญๅ‚ๆ•ฐ็š„ๅˆๆณ•ๆ€ง,ๅฆ‚ๆžœไธๅˆๆณ•็›ดๆŽฅ่ฟ”ๅ›žnil
    if (aspect_isSelectorAllowedAndTrack(self, selector, options, error)) {
        //ๅ‚ๆ•ฐๅˆๆณ•
        //ๅˆ›ๅปบๅฎนๅ™จ
        AspectsContainer *aspectContainer = aspect_getContainerForObject(self, selector);
        //ๅˆ›ๅปบไธ€ไธชAspectIdentifierๅฏน่ฑก(ไฟๅญ˜hookๅ†…ๅฎน)
        identifier = [AspectIdentifier identifierWithSelector:selector object:self options:options block:block error:error];
        if (identifier) {
            //ๆŠŠidentifierๆทปๅŠ ๅˆฐๅฎนๅ™จไธญ(ๆ นๆฎoptions,ๆทปๅŠ ๅˆฐไธๅŒ้›†ๅˆไธญ)
            [aspectContainer addAspect:identifier withOptions:options];

            // Modify the class to allow message interception.
            aspect_prepareClassAndHookSelector(self, selector, error);
        }
    }
});
return identifier;

} ไธŠ้ข็š„ๆ–นๆณ•ไธป่ฆๆ˜ฏๅˆ†ไธบไปฅไธ‹ๅ‡ ๆญฅ:

ๅˆคๆ–ญไธŠ้ขไผ ๅ…ฅ็š„ๆ–นๆณ•็š„ๅˆๆณ•ๆ€ง ๅฆ‚ๆžœๅˆๆณ•ๅฐฑๅˆ›ๅปบAspectsContainerๅฎนๅ™จ็ฑป,่ฟ™ไธชๅฎนๅ™จไผšๆ นๆฎไผ ๅ…ฅ็š„ๅˆ‡็‰‡ๆ—ถๆœบ่ฟ›่กŒๅˆ†็ฑป,ๆทปๅŠ ๅˆฐๅฏนๅบ”็š„้›†ๅˆไธญๅŽป ๅˆ›ๅปบAspectIdentifierๅฏน่ฑกไฟๅญ˜hookๅ†…ๅฎน ๅฆ‚ๆžœAspectIdentifierๅฏน่ฑกๅˆ›ๅปบๆˆๅŠŸ,ๅฐฑๆŠŠAspectIdentifierๆ นๆฎoptionsๆทปๅŠ ๅˆฐๅฏนๅบ”็š„ๆ•ฐ็ป„ไธญ ๆœ€็ปˆ่ฐƒ็”จaspect_prepareClassAndHookSelector(self, selector, error);ๅผ€ๅง‹่ฟ›่กŒhook ๆŽฅไธ‹ๆฅๅฐฑๅฏนไธŠ้ข็š„ๆญฅ้ชคไธ€ไธ€่งฃ่ฏป

ไธ€:ๅˆคๆ–ญไผ ๅ…ฅๆ–นๆณ•็š„ๅˆๆณ•ๆ€ง /* ๅˆคๆ–ญๅ‚ๆ•ฐ็š„ๅˆๆณ•ๆ€ง: 1.ๅ…ˆๅฐ†retain,release,autorelease,forwardInvocationๆทปๅŠ ๅˆฐๆ•ฐ็ป„ไธญ,ๅฆ‚ๆžœSELๆ˜ฏๆ•ฐ็ป„ไธญ็š„ๆŸไธ€ไธช,ๆŠฅ้”™ ๅนถ่ฟ”ๅ›žNO,่ฟ™ๅ‡ ไธชๅ…จๆ˜ฏไธ่ƒฝ่ฟ›่กŒSwizzle็š„ๆ–นๆณ• 2.ไผ ๅ…ฅ็š„ๆ—ถๆœบๆ˜ฏๅฆๆญฃ็กฎ,ๅˆคๆ–ญSELๆ˜ฏๅฆๆ˜ฏdealloc,ๅฆ‚ๆžœๆ˜ฏdealloc,้€‰ๆ‹ฉ็š„่ฐƒ็”จๆ—ถๆœบๅฟ…้กปๆ˜ฏAspectPositionBefore 3.ๅˆคๆ–ญ็ฑปๆˆ–่€…็ฑปๅฏน่ฑกๆ˜ฏๅฆๅ“ๅบ”ไผ ๅ…ฅ็š„sel 4.ๅฆ‚ๆžœๆ›ฟๆข็š„ๆ˜ฏ็ฑปๆ–นๆณ•,ๅˆ™่ฟ›่กŒๆ˜ฏๅฆ้‡ๅคๆ›ฟๆข็š„ๆฃ€ๆŸฅ */ static BOOL aspect_isSelectorAllowedAndTrack(NSObject *self, SEL selector, AspectOptions options, NSError **error) { static NSSet *disallowedSelectorList; static dispatch_once_t pred; dispatch_once(&pred, ^{ disallowedSelectorList = [NSSet setWithObjects:@"retain", @"release", @"autorelease", @"forwardInvocation:", nil]; });

// Check against the blacklist.
NSString *selectorName = NSStringFromSelector(selector);
if ([disallowedSelectorList containsObject:selectorName]) {
    NSString *errorDescription = [NSString stringWithFormat:@"Selector %@ is blacklisted.", selectorName];
    AspectError(AspectErrorSelectorBlacklisted, errorDescription);
    return NO;
}

// Additional checks.
AspectOptions position = options&AspectPositionFilter;
//ๅฆ‚ๆžœๆ˜ฏdeallocๅฟ…้กปๆ˜ฏAspectPositionBefore,ไธ็„ถๆŠฅ้”™
if ([selectorName isEqualToString:@"dealloc"] && position != AspectPositionBefore) {
    NSString *errorDesc = @"AspectPositionBefore is the only valid position when hooking dealloc.";
    AspectError(AspectErrorSelectorDeallocPosition, errorDesc);
    return NO;
}
//ๅˆคๆ–ญๆ˜ฏๅฆๅฏไปฅๅ“ๅบ”ๆ–นๆณ•,respondsToSelector(ๅˆคๆ–ญๅฏน่ฑกๆ˜ฏๅฆๅ“ๅบ”ๆŸไธชๆ–นๆณ•),instancesRespondToSelector(ๅˆคๆ–ญ็ฑป่ƒฝๅฆๅ“ๅบ”ๆŸไธชๆ–นๆณ•)
if (![self respondsToSelector:selector] && ![self.class instancesRespondToSelector:selector]) {
    NSString *errorDesc = [NSString stringWithFormat:@"Unable to find selector -[%@ %@].", NSStringFromClass(self.class), selectorName];
    AspectError(AspectErrorDoesNotRespondToSelector, errorDesc);
    return NO;
}

// Search for the current class and the class hierarchy IF we are modifying a class object
//ๅˆคๆ–ญๆ˜ฏไธๆ˜ฏๅ…ƒ็ฑป,
if (class_isMetaClass(object_getClass(self))) {
    Class klass = [self class];
    //ๅˆ›ๅปบๅญ—ๅ…ธ
    NSMutableDictionary *swizzledClassesDict = aspect_getSwizzledClassesDict();
    Class currentClass = [self class];
    do {
        AspectTracker *tracker = swizzledClassesDict[currentClass];
        if ([tracker.selectorNames containsObject:selectorName]) {

            // Find the topmost class for the log.
            if (tracker.parentEntry) {
                AspectTracker *topmostEntry = tracker.parentEntry;
                while (topmostEntry.parentEntry) {
                    topmostEntry = topmostEntry.parentEntry;
                }
                NSString *errorDescription = [NSString stringWithFormat:@"Error: %@ already hooked in %@. A method can only be hooked once per class hierarchy.", selectorName, NSStringFromClass(topmostEntry.trackedClass)];
                AspectError(AspectErrorSelectorAlreadyHookedInClassHierarchy, errorDescription);
                return NO;
            }else if (klass == currentClass) {
                // Already modified and topmost!
                return YES;
            }
        }
    }while ((currentClass = class_getSuperclass(currentClass)));

    // Add the selector as being modified.

//ๅˆฐๆญคๅฐฑ่กจ็คบไผ ๅ…ฅ็š„ๅ‚ๆ•ฐๅˆๆณ•,ๅนถไธ”ๆฒกๆœ‰่ขซhook่ฟ‡,ๅฐฑๅฏไปฅๆŠŠไฟกๆฏไฟๅญ˜่ตทๆฅไบ† currentClass = klass; AspectTracker *parentTracker = nil; do { AspectTracker *tracker = swizzledClassesDict[currentClass]; if (!tracker) { tracker = [[AspectTracker alloc] initWithTrackedClass:currentClass parent:parentTracker]; swizzledClassesDict[(id)currentClass] = tracker; } [tracker.selectorNames addObject:selectorName]; // All superclasses get marked as having a subclass that is modified. parentTracker = tracker; }while ((currentClass = class_getSuperclass(currentClass))); }

return YES;

} ไธŠ้ขไปฃ็ ไธป่ฆๅนฒไบ†ไธ€ไธ‹ๅ‡ ไปถไบ‹:

ๆŠŠ"retain", "release", "autorelease", "forwardInvocation:่ฟ™ๅ‡ ไธชๅŠ ๅ…ฅ้›†ๅˆไธญ,ๅˆคๆ–ญ้›†ๅˆไธญๆ˜ฏๅฆๅŒ…ๅซไผ ๅ…ฅ็š„selector,ๅฆ‚ๆžœๅŒ…ๅซ่ฟ”ๅ›žNO,่ฟ™ไนŸ่ฏดๆ˜ŽAspectsไธ่ƒฝๅฏน่ฟ™ๅ‡ ไธชๅ‡ฝๆ•ฐ่ฟ›่กŒhookๆ“ไฝœ; ๅˆคๆ–ญselectorๆ˜ฏไธๆ˜ฏdeallocๆ–นๆณ•,ๅฆ‚ๆžœๆ˜ฏๅˆ‡้ขๆ—ถๆœบๅฟ…้กปๆ˜ฏAspectPositionBefore,่ฆไธ็„ถๅฐฑไผšๆŠฅ้”™ๅนถ่ฟ”ๅ›žNO,deallocไน‹ๅŽๅฏน่ฑกๅฐฑ้”€ๆฏ,ๆ‰€ไปฅๅˆ‡็‰‡ๆ—ถๆœบๅช่ƒฝๆ˜ฏๅœจๅŽŸๆ–นๆณ•่ฐƒ็”จไน‹ๅ‰่ฐƒ็”จ ๅˆคๆ–ญ็ฑปๅ’Œๅฎžไพ‹ๅฏน่ฑกๆ˜ฏๅฆๅฏไปฅๅ“ๅบ”ไผ ๅ…ฅ็š„selector,ไธ่ƒฝๅฐฑ่ฟ”ๅ›žNO ๅˆคๆ–ญๆ˜ฏไธๆ˜ฏๅ…ƒ็ฑป,ๅฆ‚ๆžœๆ˜ฏๅ…ƒ็ฑป,ๅˆคๆ–ญๆ–นๆณ•ๆœ‰ๆฒกๆœ‰่ขซhook่ฟ‡,ๅฆ‚ๆžœๆฒกๆœ‰ๅฐฑไฟๅญ˜ๆ•ฐๆฎ,ไธ€ไธชๆ–นๆณ•ๅœจไธ€ไธช็ฑป็š„ๅฑ‚็บง้‡Œ้ขๅช่ƒฝhookไธ€ๆฌก 2.ๅˆ›ๅปบAspectsContainerๅฎนๅ™จ็ฑป // Loads or creates the aspect container. static AspectsContainer *aspect_getContainerForObject(NSObject *self, SEL selector) { NSCParameterAssert(self); //ๆ‹ผๆŽฅๅญ—็ฌฆไธฒaspects__viewDidAppear: SEL aliasSelector = aspect_aliasForSelector(selector); //่Žทๅ–aspectContainerๅฏน่ฑก AspectsContainer *aspectContainer = objc_getAssociatedObject(self, aliasSelector); //ๅฆ‚ๆžœไธŠ้ขๆฒกๆœ‰่Žทๅ–ๅˆฐๅฐฑๅˆ›ๅปบ if (!aspectContainer) { aspectContainer = [AspectsContainer new]; objc_setAssociatedObject(self, aliasSelector, aspectContainer, OBJC_ASSOCIATION_RETAIN); } return aspectContainer; } ่Žทๅพ—ๅ…ถๅฏนๅบ”็š„AssociatedObjectๅ…ณ่”ๅฏน่ฑก๏ผŒๅฆ‚ๆžœ่Žทๅ–ไธๅˆฐ๏ผŒๅฐฑๅˆ›ๅปบไธ€ไธชๅ…ณ่”ๅฏน่ฑกใ€‚ๆœ€็ปˆๅพ—ๅˆฐselectorๆœ‰"aspects_"ๅ‰็ผ€๏ผŒๅฏนๅบ”็š„aspectContainerใ€‚

3.ๅˆ›ๅปบAspectIdentifierๅฏน่ฑกไฟๅญ˜hookๅ†…ๅฎน

  • (instancetype)identifierWithSelector:(SEL)selector object:(id)object options:(AspectOptions)options block:(id)block error:(NSError **)error { NSCParameterAssert(block); NSCParameterAssert(selector); // /ๆŠŠblcok่ฝฌๆขๆˆๆ–นๆณ•็ญพๅ NSMethodSignature *blockSignature = aspect_blockMethodSignature(block, error); // TODO: check signature compatibility, etc. //aspect_isCompatibleBlockSignature ๅฏนๆฏ”่ฆๆ›ฟๆขๆ–นๆณ•็š„blockๅ’ŒๅŽŸๆ–นๆณ•,ๅฆ‚ๆžœไธไธ€ๆ ท,ไธ็ปง็ปญ่ฟ›่กŒ //ๅฆ‚ๆžœไธ€ๆ ท,ๆŠŠๆ‰€ๆœ‰็š„ๅ‚ๆ•ฐ่ต‹ๅ€ผ็ป™AspectIdentifierๅฏน่ฑก if (!aspect_isCompatibleBlockSignature(blockSignature, object, selector, error)) { return nil; }

    AspectIdentifier *identifier = nil;

    if (blockSignature) { identifier = [AspectIdentifier new]; identifier.selector = selector; identifier.block = block; identifier.blockSignature = blockSignature; identifier.options = options; identifier.object = object; // weak } return identifier; } /* 1.ๆŠŠๅŽŸๆ–นๆณ•่ฝฌๆขๆˆๆ–นๆณ•็ญพๅ 2.็„ถๅŽๆฏ”่พƒไธคไธชๆ–นๆณ•็ญพๅ็š„ๅ‚ๆ•ฐๆ•ฐ้‡,ๅฆ‚ๆžœไธ็›ธ็ญ‰,่ฏดๆ˜Žไธไธ€ๆ ท 3.ๅฆ‚ๆžœๅ‚ๆ•ฐไธชๆ•ฐ็›ธๅŒ,ๅ†ๆฏ”่พƒblockSignature็š„็ฌฌไธ€ไธชๅ‚ๆ•ฐ */ static BOOL aspect_isCompatibleBlockSignature(NSMethodSignature *blockSignature, id object, SEL selector, NSError **error) { NSCParameterAssert(blockSignature); NSCParameterAssert(object); NSCParameterAssert(selector);

    BOOL signaturesMatch = YES; //ๆŠŠๅŽŸๆ–นๆณ•่ฝฌๅŒ–ๆˆๆ–นๆณ•็ญพๅ NSMethodSignature *methodSignature = [[object class] instanceMethodSignatureForSelector:selector]; //ๅˆคๆ–ญไธคไธชๆ–นๆณ•็ผ–ๅท็š„ๅ‚ๆ•ฐๆ•ฐ้‡ if (blockSignature.numberOfArguments > methodSignature.numberOfArguments) { signaturesMatch = NO; }else { //ๅ–ๅ‡บblockSignature็š„็ฌฌไธ€ไธชๅ‚ๆ•ฐๆ˜ฏไธๆ˜ฏ_cmd,ๅฏนๅบ”็š„typeๅฐฑๆ˜ฏ'@',ๅฆ‚ๆžœไธ็ญ‰ไบŽ'@',ไนŸไธๅŒน้… if (blockSignature.numberOfArguments > 1) { const char *blockType = [blockSignature getArgumentTypeAtIndex:1]; if (blockType[0] != '@') { signaturesMatch = NO; } } // Argument 0 is self/block, argument 1 is SEL or id. We start comparing at argument 2. // The block can have less arguments than the method, that's ok. //ๅฆ‚ๆžœsignaturesMatch = yes,ไธ‹้ขๆ‰ๆ˜ฏๆฏ”่พƒไธฅๆ ผ็š„ๆฏ”่พƒ if (signaturesMatch) { for (NSUInteger idx = 2; idx < blockSignature.numberOfArguments; idx++) { const char *methodType = [methodSignature getArgumentTypeAtIndex:idx]; const char *blockType = [blockSignature getArgumentTypeAtIndex:idx]; // Only compare parameter, not the optional type data. if (!methodType || !blockType || methodType[0] != blockType[0]) { signaturesMatch = NO; break; } } } } //ๅฆ‚ๆžœ็ป่ฟ‡ไธŠ้ข็š„ๅฏนๆฏ”signaturesMatch้ƒฝไธบNO,ๆŠ›ๅ‡บๅผ‚ๅธธ if (!signaturesMatch) { NSString *description = [NSString stringWithFormat:@"Blog signature %@ doesn't match %@.", blockSignature, methodSignature]; AspectError(AspectErrorIncompatibleBlockSignature, description); return NO; } return YES; } //ๆŠŠblcok่ฝฌๆขๆˆๆ–นๆณ•็ญพๅ #pragma mark ๆŠŠblcok่ฝฌๆขๆˆๆ–นๆณ•็ญพๅ static NSMethodSignature *aspect_blockMethodSignature(id block, NSError **error) { AspectBlockRef layout = (__bridge void *)block; //ๅˆคๆ–ญๆ˜ฏๅฆๆœ‰AspectBlockFlagsHasSignatureๆ ‡ๅฟ—ไฝ,ๆฒกๆœ‰ๆŠฅไธๅŒ…ๅซๆ–นๆณ•็ญพๅ็š„error if (!(layout->flags & AspectBlockFlagsHasSignature)) { NSString *description = [NSString stringWithFormat:@"The block %@ doesn't contain a type signature.", block]; AspectError(AspectErrorMissingBlockSignature, description); return nil; } void *desc = layout->descriptor; desc += 2 * sizeof(unsigned long int); if (layout->flags & AspectBlockFlagsHasCopyDisposeHelpers) { desc += 2 * sizeof(void *); } if (!desc) { NSString *description = [NSString stringWithFormat:@"The block %@ doesn't has a type signature.", block]; AspectError(AspectErrorMissingBlockSignature, description); return nil; } const char signature = ((const char **)desc); return [NSMethodSignature signatureWithObjCTypes:signature]; } ่ฟ™ไธชๆ–นๆณ•ๅ…ˆๆŠŠblock่ฝฌๆขๆˆๆ–นๆณ•็ญพๅ,็„ถๅŽๅ’ŒๅŽŸๆฅ็š„ๆ–นๆณ•็ญพๅ่ฟ›่กŒๅฏนๆฏ”,ๅฆ‚ๆžœไธไธ€ๆ ท่ฟ”ๅ›žNO,ไธ€ๆ ทๅฐฑ่ฟ›่กŒ่ต‹ๅ€ผๆ“ไฝœ

4.ๆŠŠAspectIdentifierๆ นๆฎoptionsๆทปๅŠ ๅˆฐๅฏนๅบ”็š„ๆ•ฐ็ป„ไธญ

  • (void)addAspect:(AspectIdentifier *)aspect withOptions:(AspectOptions)options { NSParameterAssert(aspect); NSUInteger position = options&AspectPositionFilter; switch (position) { case AspectPositionBefore: self.beforeAspects = [(self.beforeAspects ?:@[]) arrayByAddingObject:aspect]; break; case AspectPositionInstead: self.insteadAspects = [(self.insteadAspects?:@[]) arrayByAddingObject:aspect]; break; case AspectPositionAfter: self.afterAspects = [(self.afterAspects ?:@[]) arrayByAddingObject:aspect]; break; } } ๆ นๆฎไผ ๅ…ฅ็š„ๅˆ‡้ขๆ—ถๆœบ,่ฟ›่กŒๅฏนๅบ”ๆ•ฐ็ป„็š„ๅญ˜ๅ‚จ;

5.ๅผ€ๅง‹่ฟ›่กŒhook aspect_prepareClassAndHookSelector(self, selector, error); ๅฐ่Š‚ไธ€ไธ‹:Aspectsๅœจhookไน‹ๅ‰ไผšๅฏนไผ ๅ…ฅ็š„ๅ‚ๆ•ฐ็š„ๅˆๆณ•ๆ€ง่ฟ›่กŒๆ ก้ชŒ,็„ถๅŽๆŠŠไผ ๅ…ฅ็š„block(ๅฐฑๆ˜ฏๅœจๅŽŸๆ–นๆณ•่ฐƒ็”จไน‹ๅ‰,ไน‹ๅŽ่ฐƒ็”จ,ๆˆ–่€…ๆ›ฟๆขๅŽŸๆ–นๆณ•็š„ไปฃ็ ๅ—)ๅ’ŒๅŽŸๆ–นๆณ•้ƒฝ่ฝฌๆขๆˆๆ–นๆณ•็ญพๅ่ฟ›่กŒๅฏนๆฏ”,ๅฆ‚ๆžœไธ€่‡ดๅฐฑๆŠŠๆ‰€ๆœ‰ไฟกๆฏไฟๅญ˜ๅˆฐAspectIdentifier่ฟ™ไธช็ฑป้‡Œ้ข(ๅŽๆœŸ่ฐƒ็”จ่ฟ™ไธชblock็š„ๆ—ถๅ€™ไผš็”จๅˆฐ่ฟ™ไบ›ไฟกๆฏ),็„ถๅŽไผšๆ นๆฎไผ ่ฟ›ๆฅ็š„ๅˆ‡้ขๆ—ถๆœบไฟๅญ˜ๅˆฐAspectsContainer่ฟ™ไธช็ฑป้‡Œๅฏนๅบ”็š„ๆ•ฐ็ป„ไธญ(ๆœ€ๅŽ้€š่ฟ‡้ๅŽ†,่Žทๅ–ๅˆฐๅ…ถไธญ็š„ไธ€ไธชAspectIdentifierๅฏน่ฑก,่ฐƒ็”จinvokeWithInfoๆ–นๆณ•),ๅ‡†ๅค‡ๅทฅไฝœๅšๅฎŒไปฅๅŽๅผ€ๅง‹ๅฏน็ฑปๅ’Œๆ–นๆณ•่ฟ›่กŒHookๆ“ไฝœไบ†

ไบŒ:Aspectsๆ˜ฏๆ€Žไนˆๅฏน็ฑปๅ’Œๆ–นๆณ•่ฟ›่กŒHook็š„? ๅ…ˆๅฏนclass่ฟ›่กŒhookๅ†ๅฏนselector่ฟ›่กŒhook

1.Hook Class static Class aspect_hookClass(NSObject *self, NSError **error) { NSCParameterAssert(self); //่Žทๅ–็ฑป Class statedClass = self.class; //่Žทๅ–็ฑป็š„isaๆŒ‡้’ˆ Class baseClass = object_getClass(self);

NSString *className = NSStringFromClass(baseClass);

// Already subclassed
//ๅˆคๆ–ญๆ˜ฏๅฆๅŒ…ๅซ_Aspects_,ๅฆ‚ๆžœๅŒ…ๅซ,ๅฐฑ่ฏดๆ˜Ž่ขซhook่ฟ‡ไบ†,
//ๅฆ‚ๆžœไธๅŒ…ๅซ_Aspects_,ๅ†ๅˆคๆ–ญๆ˜ฏไธๆ˜ฏๅ…ƒ็ฑป,ๅฆ‚ๆžœๆ˜ฏๅ…ƒ็ฑป่ฐƒ็”จaspect_swizzleClassInPlace
//ๅฆ‚ๆžœไธๅŒ…ๅซ_Aspects_,ไนŸไธๆ˜ฏๅ…ƒ็ฑป,ๅ†ๅˆคๆ–ญstatedClassๅ’ŒbaseClassๆ˜ฏๅฆ็›ธ็ญ‰,ๅฆ‚ๆžœไธ็›ธ็ญ‰,่ฏดๆ˜Žๆ˜ฏ่ขซkvo่ฟ‡็š„ๅฏน่ฑกๅ› ไธบkvoๅฏน่ฑก็š„isaๆŒ‡้’ˆๆŒ‡ๅ‘ไบ†ๅฆไธ€ไธชไธญ้—ด็ฑป,่ฐƒ็”จaspect_swizzleClassInPlace

if ([className hasSuffix:AspectsSubclassSuffix]) {
    return baseClass;

    // We swizzle a class object, not a single object.
}else if (class_isMetaClass(baseClass)) {
    return aspect_swizzleClassInPlace((Class)self);
    // Probably a KVO'ed class. Swizzle in place. Also swizzle meta classes in place.
}else if (statedClass != baseClass) {
    return aspect_swizzleClassInPlace(baseClass);
}

// Default case. Create dynamic subclass.
//ๅฆ‚ๆžœไธๆ˜ฏๅ…ƒ็ฑป,ไนŸไธๆ˜ฏ่ขซkvo่ฟ‡็š„็ฑป,ไนŸๆฒกๆœ‰่ขซhook่ฟ‡,ๅฐฑ็ปง็ปญๅพ€ไธ‹ๆ‰ง่กŒ,ๅˆ›ๅปบไธ€ไธชๅญ็ฑป,
//ๆ‹ผๆŽฅ็ฑปๅไธบXXX_Aspects_
const char *subclassName = [className stringByAppendingString:AspectsSubclassSuffix].UTF8String;
//ๆ นๆฎๆ‹ผๆŽฅ็š„็ฑปๅ่Žทๅ–็ฑป
Class subclass = objc_getClass(subclassName);
//ๅฆ‚ๆžœไธŠ้ข่Žทๅ–ๅˆฐ็š„ไบ†ไธบnil
if (subclass == nil) {
    //baseClass = MainViewController,ๅˆ›ๅปบไธ€ไธชๅญ็ฑปMainViewController_Aspects_
    subclass = objc_allocateClassPair(baseClass, subclassName, 0);
    //ๅฆ‚ๆžœๅญ็ฑปๅˆ›ๅปบๅคฑ่ดฅ,ๆŠฅ้”™
    if (subclass == nil) {
        NSString *errrorDesc = [NSString stringWithFormat:@"objc_allocateClassPair failed to allocate class %s.", subclassName];
        AspectError(AspectErrorFailedToAllocateClassPair, errrorDesc);
        return nil;
    }

    aspect_swizzleForwardInvocation(subclass);
    //ๆŠŠsubclass็š„isaๆŒ‡ๅ‘ไบ†statedClass
    aspect_hookedGetClass(subclass, statedClass);
    //subclass็š„ๅ…ƒ็ฑป็š„isa๏ผŒไนŸๆŒ‡ๅ‘ไบ†statedClassใ€‚
    aspect_hookedGetClass(object_getClass(subclass), statedClass);
    //ๆณจๅ†Œๅˆšๅˆšๆ–ฐๅปบ็š„ๅญ็ฑปsubclass๏ผŒๅ†่ฐƒ็”จobject_setClass(self, subclass);ๆŠŠๅฝ“ๅ‰self็š„isaๆŒ‡ๅ‘ๅญ็ฑปsubclass
    objc_registerClassPair(subclass);
}

object_setClass(self, subclass);
return subclass;

} ๅˆคๆ–ญclassNameไธญๆ˜ฏๅฆๅŒ…ๅซ_Aspects_,ๅฆ‚ๆžœๅŒ…ๅซๅฐฑ่ฏดๆ˜Ž่ฟ™ไธช็ฑปๅทฒ็ป่ขซHook่ฟ‡ไบ†็›ดๆŽฅ่ฟ”ๅ›ž่ฟ™ไธช็ฑป็š„isaๆŒ‡้’ˆ ๅฆ‚ๆžœไธๅŒ…ๅซๅˆคๆ–ญๅœจๅˆคๆ–ญๆ˜ฏไธๆ˜ฏๅ…ƒ็ฑป,ๅฆ‚ๆžœๆ˜ฏๅฐฑ่ฐƒ็”จaspect_swizzleClassInPlace() ๅฆ‚ๆžœไธๅŒ…ๅซไนŸไธๆ˜ฏๅ…ƒ็ฑป,ๅ†ๅˆคๆ–ญbaseClassๅ’ŒstatedClassๆ˜ฏๅฆ็›ธ็ญ‰,ๅฆ‚ๆžœไธ็›ธ็ญ‰,่ฏดๆ˜Žๆ˜ฏ่ขซKVO่ฟ‡็š„ๅฏน่ฑก ๅฆ‚ๆžœไธๆ˜ฏๅ…ƒ็ฑปไนŸไธๆ˜ฏ่ขซkvo่ฟ‡็š„็ฑปๅฐฑ็ปง็ปญๅ‘ไธ‹ๆ‰ง่กŒ,ๅˆ›ๅปบไธ€ไธชๅญ็ฑป,็ฑปๅไธบๅŽŸๆฅ็ฑปๅ+Aspects,ๅˆ›ๅปบๆˆๅŠŸ่ฐƒ็”จaspect_swizzleForwardInvocation()ไบคๆขIMP,ๆŠŠๆ–ฐๅปบ็ฑป็š„forwardInvocationIMPๆ›ฟๆขไธบ__ASPECTS_ARE_BEING_CALLED__,็„ถๅŽๆŠŠsubClass็š„isaๆŒ‡้’ˆๆŒ‡ๅ‘statedCass,subclass็š„ๅ…ƒ็ฑป็š„isaๆŒ‡้’ˆไนŸๆŒ‡ๅ‘statedClass,็„ถๅŽๆณจๅ†Œๆ–ฐๅˆ›ๅปบ็š„ๅญ็ฑปsubClass,ๅ†่ฐƒ็”จobject_setClass(self, subclass);ๆŠŠๅฝ“ๅ‰self็š„isaๆŒ‡้’ˆๆŒ‡ๅ‘ๅญ็ฑปsubClass aspect_swizzleClassInPlace() static Class aspect_swizzleClassInPlace(Class klass) { NSCParameterAssert(klass); NSString *className = NSStringFromClass(klass); //ๅˆ›ๅปบๆ— ๅบ้›†ๅˆ aspect_modifySwizzledClasses(^(NSMutableSet *swizzledClasses) { //ๅฆ‚ๆžœ้›†ๅˆไธญไธๅŒ…ๅซclassName,ๆทปๅŠ ๅˆฐ้›†ๅˆไธญ if (![swizzledClasses containsObject:className]) { aspect_swizzleForwardInvocation(klass); [swizzledClasses addObject:className]; } }); return klass; } ่ฟ™ไธชๅ‡ฝๆ•ฐไธป่ฆๆ˜ฏ:้€š่ฟ‡่ฐƒ็”จaspect_swizzleForwardInvocation ()ๅ‡ฝๆ•ฐๆŠŠ็ฑป็š„forwardInvocationIMPๆ›ฟๆขไธบ__ASPECTS_ARE_BEING_CALLED_,็„ถๅŽๆŠŠ็ฑปๅๆทปๅŠ ๅˆฐ้›†ๅˆไธญ(่ฟ™ไธช้›†ๅˆๅŽๆœŸๅˆ ้™คHook็š„ๆ—ถๅ€™ไผš็”จๅˆฐ็š„)

aspect_swizzleForwardInvocation(Class klass) static void aspect_swizzleForwardInvocation(Class klass) { NSCParameterAssert(klass); // If there is no method, replace will act like class_addMethod. //ๆŠŠforwardInvocation็š„IMPๆ›ฟๆขๆˆ__ASPECTS_ARE_BEING_CALLED__ //class_replaceMethod่ฟ”ๅ›ž็š„ๆ˜ฏๅŽŸๆ–นๆณ•็š„IMP IMP originalImplementation = class_replaceMethod(klass, @selector(forwardInvocation:), (IMP)ASPECTS_ARE_BEING_CALLED, "v@:@"); // originalImplementationไธไธบ็ฉบ็š„่ฏ่ฏดๆ˜ŽๅŽŸๆ–นๆณ•ๆœ‰ๅฎž็Žฐ๏ผŒๆทปๅŠ ไธ€ไธชๆ–ฐๆ–นๆณ•__aspects_forwardInvocation:ๆŒ‡ๅ‘ไบ†ๅŽŸๆฅ็š„originalImplementation๏ผŒๅœจ__ASPECTS_ARE_BEING_CALLED__้‚ฃ้‡Œๅฆ‚ๆžœไธ่ƒฝๅค„็†๏ผŒๅˆคๆ–ญๆ˜ฏๅฆๆœ‰ๅฎž็Žฐ__aspects_forwardInvocation๏ผŒๆœ‰็š„่ฏๅฐฑ่ฝฌๅ‘ใ€‚

if (originalImplementation) {
    class_addMethod(klass, NSSelectorFromString(AspectsForwardInvocationSelectorName), originalImplementation, "v@:@");
}
AspectLog(@"Aspects: %@ is now aspect aware.", NSStringFromClass(klass));

} ไบคๆขๆ–นๆณ•ๅฎž็ŽฐIMP,ๆŠŠforwardInvocation:็š„IMPๆ›ฟๆขๆˆ__ASPECTS_ARE_BEING_CALLED__,่ฟ™ๆ ทๅš็š„็›ฎ็š„ๆ˜ฏ:ๅœจๆŠŠselector่ฟ›่กŒhookไปฅๅŽไผšๆŠŠๅŽŸๆฅ็š„ๆ–นๆณ•็š„IMPๆŒ‡ๅ‘objc_forward,็„ถๅŽๅฐฑไผš่ฐƒ็”จforwardInvocation :,ๅ› ไธบforwardInvocation :็š„IMPๆŒ‡ๅ‘็š„ๆ˜ฏ__ASPECTS_ARE_BEING_CALLED__ๅ‡ฝๆ•ฐ,ๆœ€็ปˆๅฐฑไผš่ฐƒ็”จๅˆฐ่ฟ™้‡Œๆฅ,ๅœจ่ฟ™้‡Œ้ขๆ‰ง่กŒhookไปฃ็ ๅ’ŒๅŽŸๆ–นๆณ•,ๅฆ‚ๆžœๅŽŸๆฅ็š„็ฑปๆœ‰ๅฎž็ŽฐforwardInvocation :่ฟ™ไธชๆ–นๆณ•,ๅฐฑๆŠŠ่ฟ™ไธชๆ–นๆณ•็š„IMPๆŒ‡ๅ‘__aspects_forwardInvocation:

aspect_hookedGetClass static void aspect_hookedGetClass(Class class, Class statedClass) { NSCParameterAssert(class); NSCParameterAssert(statedClass); Method method = class_getInstanceMethod(class, @selector(class)); IMP newIMP = imp_implementationWithBlock(^(id self) { return statedClass; }); class_replaceMethod(class, @selector(class), newIMP, method_getTypeEncoding(method)); } ๆ นๆฎไผ ้€’็š„ๅ‚ๆ•ฐ,ๆŠŠๆ–ฐๅˆ›ๅปบ็š„็ฑปๅ’Œ่ฏฅ็ฑป็š„ๅ…ƒ็ฑป็š„classๆ–นๆณ•็š„IMPๆŒ‡ๅ‘ๅŽŸๆฅ็š„็ฑป(ไปฅๅŽๆ–ฐๅปบ็š„็ฑปๅ†่ฐƒ็”จclassๆ–นๆณ•,่ฟ”ๅ›ž็š„้ƒฝๆ˜ฏstatedClass)

object_setClass(self, subclass); ๆŠŠๅŽŸๆฅ็ฑป็š„isaๆŒ‡้’ˆๆŒ‡ๅ‘ๆ–ฐๅˆ›ๅปบ็š„็ฑป

ๆŽฅไธ‹ๆฅๅ†่ฏด่ฏดๆ˜ฏๆ€Žไนˆๅฏนmethod่ฟ›่กŒhook็š„

static void aspect_prepareClassAndHookSelector(NSObject *self, SEL selector, NSError **error) { NSCParameterAssert(selector); Class klass = aspect_hookClass(self, error); Method targetMethod = class_getInstanceMethod(klass, selector); IMP targetMethodIMP = method_getImplementation(targetMethod); if (!aspect_isMsgForwardIMP(targetMethodIMP)) { // Make a method alias for the existing method implementation, it not already copied. const char *typeEncoding = method_getTypeEncoding(targetMethod); SEL aliasSelector = aspect_aliasForSelector(selector); //ๅญ็ฑป้‡Œ้ขไธ่ƒฝๅ“ๅบ”aspects_xxxx๏ผŒๅฐฑไธบklassๆทปๅŠ aspects_xxxxๆ–นๆณ•๏ผŒๆ–นๆณ•็š„ๅฎž็ŽฐไธบๅŽŸ็”Ÿๆ–นๆณ•็š„ๅฎž็Žฐ if (![klass instancesRespondToSelector:aliasSelector]) { __unused BOOL addedAlias = class_addMethod(klass, aliasSelector, method_getImplementation(targetMethod), typeEncoding); NSCAssert(addedAlias, @"Original implementation for %@ is already copied to %@ on %@", NSStringFromSelector(selector), NSStringFromSelector(aliasSelector), klass); }

    // We use forwardInvocation to hook in.
    class_replaceMethod(klass, selector, aspect_getMsgForwardIMP(self, selector), typeEncoding);
    AspectLog(@"Aspects: Installed hook for -[%@ %@].", klass, NSStringFromSelector(selector));
}

} ไธŠ้ข็š„ไปฃ็ ไธป่ฆๆ˜ฏๅฏนselector่ฟ›่กŒhook,้ฆ–ๅ…ˆ่Žทๅ–ๅˆฐๅŽŸๆฅ็š„ๆ–นๆณ•,็„ถๅŽๅˆคๆ–ญๅˆคๆ–ญๆ˜ฏไธๆ˜ฏๆŒ‡ๅ‘ไบ†_objc_msgForward,ๆฒกๆœ‰็š„่ฏ,ๅฐฑ่Žทๅ–ๅŽŸๆฅๆ–นๆณ•็š„ๆ–นๆณ•็ผ–็ ,ไธบๆ–ฐๅปบ็š„ๅญ็ฑปๆทปๅŠ ไธ€ไธชๆ–นๆณ•aspects__xxxxx,ๅนถๅฐ†ๆ–ฐๅปบๆ–นๆณ•็š„IMPๆŒ‡ๅ‘ๅŽŸๆฅๆ–นๆณ•,ๅ†ๆŠŠๅŽŸๆฅ็ฑป็š„ๆ–นๆณ•็š„IMPๆŒ‡ๅ‘_objc_msgForward,hookๅฎŒๆฏ•

ไธ‰:ASPECTS_ARE_BEING_CALLED static void ASPECTS_ARE_BEING_CALLED(__unsafe_unretained NSObject *self, SEL selector, NSInvocation *invocation) { NSCParameterAssert(self); NSCParameterAssert(invocation); //่Žทๅ–ๅŽŸๅง‹็š„selector SEL originalSelector = invocation.selector; //่Žทๅ–ๅธฆๆœ‰aspects_xxxxๅ‰็ผ€็š„ๆ–นๆณ• SEL aliasSelector = aspect_aliasForSelector(invocation.selector); //ๆ›ฟๆขselector invocation.selector = aliasSelector; //่Žทๅ–ๅฎžไพ‹ๅฏน่ฑก็š„ๅฎนๅ™จobjectContainer๏ผŒ่ฟ™้‡Œๆ˜ฏไน‹ๅ‰aspect_addๅ…ณ่”่ฟ‡็š„ๅฏน่ฑก AspectsContainer *objectContainer = objc_getAssociatedObject(self, aliasSelector); //่Žทๅ–่Žทๅพ—็ฑปๅฏน่ฑกๅฎนๅ™จclassContainer AspectsContainer *classContainer = aspect_getContainerForClass(object_getClass(self), aliasSelector); //ๅˆๅง‹ๅŒ–AspectInfo๏ผŒไผ ๅ…ฅselfใ€invocationๅ‚ๆ•ฐ AspectInfo *info = [[AspectInfo alloc] initWithInstance:self invocation:invocation]; NSArray *aspectsToRemove = nil;

// Before hooks.
//่ฐƒ็”จๅฎๅฎšไน‰ๆ‰ง่กŒAspectsๅˆ‡็‰‡ๅŠŸ่ƒฝ
//ๅฎๅฎšไน‰้‡Œ้ขๅฐฑๅšไบ†ไธคไปถไบ‹ๆƒ…๏ผŒไธ€ไธชๆ˜ฏๆ‰ง่กŒไบ†[aspect invokeWithInfo:info]ๆ–นๆณ•๏ผŒไธ€ไธชๆ˜ฏๆŠŠ้œ€่ฆremove็š„AspectsๅŠ ๅ…ฅ็ญ‰ๅพ…่ขซ็งป้™ค็š„ๆ•ฐ็ป„ไธญใ€‚
aspect_invoke(classContainer.beforeAspects, info);
aspect_invoke(objectContainer.beforeAspects, info);

// Instead hooks.
BOOL respondsToAlias = YES;
if (objectContainer.insteadAspects.count || classContainer.insteadAspects.count) {
    aspect_invoke(classContainer.insteadAspects, info);
    aspect_invoke(objectContainer.insteadAspects, info);
}else {
    Class klass = object_getClass(invocation.target);
    do {
        if ((respondsToAlias = [klass instancesRespondToSelector:aliasSelector])) {
            [invocation invoke];
            break;
        }
    }while (!respondsToAlias && (klass = class_getSuperclass(klass)));
}

// After hooks.
aspect_invoke(classContainer.afterAspects, info);
aspect_invoke(objectContainer.afterAspects, info);

// If no hooks are installed, call original implementation (usually to throw an exception)
if (!respondsToAlias) {
    invocation.selector = originalSelector;
    SEL originalForwardInvocationSEL = NSSelectorFromString(AspectsForwardInvocationSelectorName);
    if ([self respondsToSelector:originalForwardInvocationSEL]) {
        ((void( *)(id, SEL, NSInvocation *))objc_msgSend)(self, originalForwardInvocationSEL, invocation);
    }else {
        [self doesNotRecognizeSelector:invocation.selector];
    }
}

// Remove any hooks that are queued for deregistration.
[aspectsToRemove makeObjectsPerformSelector:@selector(remove)];

} #define aspect_invoke(aspects, info)
for (AspectIdentifier *aspect in aspects) {
[aspect invokeWithInfo:info];
if (aspect.options & AspectOptionAutomaticRemoval) {
aspectsToRemove = [aspectsToRemove?:@[] arrayByAddingObject:aspect];
}
}

  • (BOOL)invokeWithInfo:(id)info { NSInvocation *blockInvocation = [NSInvocation invocationWithMethodSignature:self.blockSignature]; NSInvocation *originalInvocation = info.originalInvocation; NSUInteger numberOfArguments = self.blockSignature.numberOfArguments;

    // Be extra paranoid. We already check that on hook registration. if (numberOfArguments > originalInvocation.methodSignature.numberOfArguments) { AspectLogError(@"Block has too many arguments. Not calling %@", info); return NO; }

    // The self of the block will be the AspectInfo. Optional. if (numberOfArguments > 1) { [blockInvocation setArgument:&info atIndex:1]; }

    void *argBuf = NULL; //ๆŠŠoriginalInvocationไธญ็š„ๅ‚ๆ•ฐ for (NSUInteger idx = 2; idx < numberOfArguments; idx++) { const char *type = [originalInvocation.methodSignature getArgumentTypeAtIndex:idx]; NSUInteger argSize; NSGetSizeAndAlignment(type, &argSize, NULL);

      if (!(argBuf = reallocf(argBuf, argSize))) {
          AspectLogError(@"Failed to allocate memory for block invocation.");
          return NO;
      }
      
      [originalInvocation getArgument:argBuf atIndex:idx];
      [blockInvocation setArgument:argBuf atIndex:idx];
    

    }

    [blockInvocation invokeWithTarget:self.block];

    if (argBuf != NULL) { free(argBuf); } return YES; } ่Žทๅ–ๆ•ฐๆฎไผ ้€’ๅˆฐaspect_invoke้‡Œ้ข,่ฐƒ็”จinvokeWithInfo,ๆ‰ง่กŒๅˆ‡้ขไปฃ็ ๅ—,ๆ‰ง่กŒๅฎŒไปฃ็ ๅ—ไปฅๅŽ,่Žทๅ–ๅˆฐๆ–ฐๅˆ›ๅปบ็š„็ฑป,ๅˆคๆ–ญๆ˜ฏๅฆๅฏไปฅๅ“ๅบ”aspects__xxxxๆ–นๆณ•,็Žฐๅœจaspects__xxxxๆ–นๆณ•ๆŒ‡ๅ‘็š„ๆ˜ฏๅŽŸๆฅๆ–นๆณ•ๅฎž็Žฐ็š„IMP,ๅฆ‚ๆžœๅฏไปฅๅ“ๅบ”,ๅฐฑ้€š่ฟ‡[invocation invoke];่ฐƒ็”จ่ฟ™ไธชๆ–นๆณ•,ๅฆ‚ๆžœไธ่ƒฝๅ“ๅบ”ๅฐฑ่ฐƒ็”จ__aspects_forwardInvocation:่ฟ™ไธชๆ–นๆณ•,่ฟ™ไธชๆ–นๆณ•ๅœจhookClass็š„ๆ—ถๅ€™ๆๅˆฐไบ†,ๅฎƒ็š„IMPๆŒ‡้’ˆๆŒ‡ๅ‘ไบ†ๅŽŸๆฅ็ฑปไธญ็š„forwardInvocation:ๅฎž็Žฐ,ๅฏไปฅๅ“ๅบ”ๅฐฑๅŽปๆ‰ง่กŒ,ไธ่ƒฝๅ“ๅบ”ๅฐฑๆŠ›ๅ‡บๅผ‚ๅธธdoesNotRecognizeSelector; ๆ•ดไธชๆต็จ‹ๅทฎไธๅคšๅฐฑ่ฟ™ไบ›,ๆœ€ๅŽ่ฟ˜ๆœ‰ไธ€ไธช็งป้™ค็š„ๆ“ไฝœ

ๅ››:็งป้™คAspects

  • (BOOL)remove { return aspect_remove(self, NULL); } static BOOL aspect_remove(AspectIdentifier *aspect, NSError **error) { NSCAssert([aspect isKindOfClass:AspectIdentifier.class], @"Must have correct type.");

    __block BOOL success = NO; aspect_performLocked(^{ id self = aspect.object; // strongify if (self) { AspectsContainer *aspectContainer = aspect_getContainerForObject(self, aspect.selector); success = [aspectContainer removeAspect:aspect];

          aspect_cleanupHookedClassAndSelector(self, aspect.selector);
          // destroy token
          aspect.object = nil;
          aspect.block = nil;
          aspect.selector = NULL;
      }else {
          NSString *errrorDesc = [NSString stringWithFormat:@"Unable to deregister hook. Object already deallocated: %@", aspect];
          AspectError(AspectErrorRemoveObjectAlreadyDeallocated, errrorDesc);
      }
    

    }); return success; } ่ฐƒ็”จremoveๆ–นๆณ•,็„ถๅŽๆธ…็ฉบAspectsContainer้‡Œ้ข็š„ๆ•ฐๆฎ,่ฐƒ็”จaspect_cleanupHookedClassAndSelectorๆธ…้™คๆ›ดๅคš็š„ๆ•ฐๆฎ

// Will undo the runtime changes made. static void aspect_cleanupHookedClassAndSelector(NSObject *self, SEL selector) { NSCParameterAssert(self); NSCParameterAssert(selector);

Class klass = object_getClass(self);
BOOL isMetaClass = class_isMetaClass(klass);
if (isMetaClass) {
    klass = (Class)self;
}

// Check if the method is marked as forwarded and undo that.
Method targetMethod = class_getInstanceMethod(klass, selector);
IMP targetMethodIMP = method_getImplementation(targetMethod);
//ๅˆคๆ–ญselectorๆ˜ฏไธๆ˜ฏๆŒ‡ๅ‘ไบ†_objc_msgForward
if (aspect_isMsgForwardIMP(targetMethodIMP)) {
    // Restore the original method implementation.
    //่Žทๅ–ๅˆฐๆ–นๆณ•็ผ–็ 
    const char *typeEncoding = method_getTypeEncoding(targetMethod);
    //ๆ‹ผๆŽฅselector
    SEL aliasSelector = aspect_aliasForSelector(selector);
    Method originalMethod = class_getInstanceMethod(klass, aliasSelector);
    //่Žทๅ–ๆ–ฐๆทปๅŠ ็ฑปไธญaspects__xxxxๆ–นๆณ•็š„IMP
    IMP originalIMP = method_getImplementation(originalMethod);
    NSCAssert(originalMethod, @"Original implementation for %@ not found %@ on %@", NSStringFromSelector(selector), NSStringFromSelector(aliasSelector), klass);
    //ๆŠŠaspects__xxxxๆ–นๆณ•็š„IMPๆŒ‡ๅ›žๅ…ƒ็ฑป็ฑป็š„ๆ–นๆณ•
    class_replaceMethod(klass, selector, originalIMP, typeEncoding);
    AspectLog(@"Aspects: Removed hook for -[%@ %@].", klass, NSStringFromSelector(selector));
}

// Deregister global tracked selector
aspect_deregisterTrackedSelector(self, selector);

// Get the aspect container and check if there are any hooks remaining. Clean up if there are not.
AspectsContainer *container = aspect_getContainerForObject(self, selector);
if (!container.hasAspects) {
    // Destroy the container
    aspect_destroyContainerForObject(self, selector);

    // Figure out how the class was modified to undo the changes.
    NSString *className = NSStringFromClass(klass);
    if ([className hasSuffix:AspectsSubclassSuffix]) {
        Class originalClass = NSClassFromString([className stringByReplacingOccurrencesOfString:AspectsSubclassSuffix withString:@""]);
        NSCAssert(originalClass != nil, @"Original class must exist");
        object_setClass(self, originalClass);
        AspectLog(@"Aspects: %@ has been restored.", NSStringFromClass(originalClass));

        // We can only dispose the class pair if we can ensure that no instances exist using our subclass.
        // Since we don't globally track this, we can't ensure this - but there's also not much overhead in keeping it around.
        //objc_disposeClassPair(object.class);
    }else {
        // Class is most likely swizzled in place. Undo that.
        if (isMetaClass) {
            aspect_undoSwizzleClassInPlace((Class)self);
        }
    }
}

} ไธŠ่ฟฐไปฃ็ ไธป่ฆๅšไปฅไธ‹ๅ‡ ไปถไบ‹:

  1. ่Žทๅ–ๅŽŸๆฅ็ฑป็š„ๆ–นๆณ•็š„IMPๆ˜ฏไธๆ˜ฏๆŒ‡ๅ‘ไบ†_objc_msgForward,ๅฆ‚ๆžœๆ˜ฏๅฐฑๆŠŠ่ฏฅๆ–นๆณ•็š„IMPๅ†ๆŒ‡ๅ›žๅŽป
  2. ๅฆ‚ๆžœๆ˜ฏๅ…ƒ็ฑปๅฐฑๅˆ ้™คswizzledClasses้‡Œ้ข็š„ๆ•ฐๆฎ
  3. ๆŠŠๆ–ฐๅปบ็ฑป็š„isaๆŒ‡้’ˆๆŒ‡ๅ‘ๅŽŸๆฅ็ฑป, ๅ…ถๅฎžๅฐฑๆ˜ฏๆŠŠhook็š„ๆ—ถๅ€™ๅš็š„ๅค„็†,ๅˆ่ฟ˜ๅŽŸไบ†

ๆญๅปบไธชไบบๅšๅฎข

ไป€ไนˆๆ˜ฏHexo๏ผŸ

Hexo ๆ˜ฏไธ€ไธชๅฟซ้€Ÿใ€็ฎ€ๆดไธ”้ซ˜ๆ•ˆ็š„ๅšๅฎขๆก†ๆžถใ€‚Hexo ไฝฟ็”จ Markdown๏ผˆๆˆ–ๅ…ถไป–ๆธฒๆŸ“ๅผ•ๆ“Ž๏ผ‰่งฃๆžๆ–‡็ซ ๏ผŒๅœจๅ‡ ็ง’ๅ†…๏ผŒๅณๅฏๅˆฉ็”จ้“ไธฝ็š„ไธป้ข˜็”Ÿๆˆ้™ๆ€็ฝ‘้กตใ€‚

ๅฎ˜ๆ–นๆ–‡ๆกฃ๏ผšhttps://hexo.io/zh-cn/docs/ 1.ๅฎ‰่ฃ…Hexo ๅฎ‰่ฃ… Hexo ็›ธๅฝ“็ฎ€ๅ•ใ€‚็„ถ่€Œๅœจๅฎ‰่ฃ…ๅ‰๏ผŒๆ‚จๅฟ…้กปๆฃ€ๆŸฅ็”ต่„‘ไธญๆ˜ฏๅฆๅทฒๅฎ‰่ฃ…ไธ‹ๅˆ—ๅบ”็”จ็จ‹ๅบ๏ผš

Node.js Git ๅฆ‚ๆžœๆ‚จ็š„็”ต่„‘ไธญๅทฒ็ปๅฎ‰่ฃ…ไธŠ่ฟฐๅฟ…ๅค‡็จ‹ๅบ๏ผŒ้‚ฃไนˆๆญๅ–œๆ‚จ๏ผๆŽฅไธ‹ๆฅๅช้œ€่ฆไฝฟ็”จ npm ๅณๅฏๅฎŒๆˆ Hexo ็š„ๅฎ‰่ฃ…ใ€‚ ็ปˆ็ซฏ่พ“ๅ…ฅ๏ผš(ไธ€ๅฎš่ฆๅŠ ไธŠsudo๏ผŒๅฆๅˆ™ไผšๅ› ไธบๆƒ้™้—ฎ้ข˜ๆŠฅ้”™)

$ sudo npm install -g hexo-cli

็ปˆ็ซฏ่พ“ๅ…ฅ๏ผšๆŸฅ็œ‹ๅฎ‰่ฃ…็š„็‰ˆๆœฌ๏ผŒๆฃ€ๆŸฅๆ˜ฏๅฆๅทฒๅฎ‰่ฃ…ๆˆๅŠŸ๏ผ

$ hexo -v  // ๆ˜พ็คบ Hexo ็‰ˆๆœฌ

2.ๅปบ็ซ™ ๅฎ‰่ฃ… Hexo ๅฎŒๆˆๅŽ๏ผŒ่ฏทๆ‰ง่กŒไธ‹ๅˆ—ๅ‘ฝไปค๏ผŒHexo ๅฐ†ไผšๅœจๆŒ‡ๅฎšๆ–‡ไปถๅคนไธญๆ–ฐๅปบๆ‰€้œ€่ฆ็š„ๆ–‡ไปถใ€‚

// ๆ–ฐๅปบ็ฉบๆ–‡ไปถๅคน
$ cd /Users/renbo/Workspaces/BlogProject
// ๅˆๅง‹ๅŒ–
$ hexo init 
$ npm install

ๆ–ฐๅปบๅฎŒๆˆๅŽ๏ผŒๆŒ‡ๅฎšๆ–‡ไปถๅคน็š„็›ฎๅฝ•ๅฆ‚ไธ‹๏ผš

็›ฎๅฝ•็ป“ๆž„ๅ›พ

_config.yml๏ผš็ฝ‘็ซ™็š„ ้…็ฝฎ ไฟกๆฏ๏ผŒๆ‚จๅฏไปฅๅœจๆญค้…็ฝฎๅคง้ƒจๅˆ†็š„ๅ‚ๆ•ฐใ€‚ scaffolds๏ผšๆจก็‰ˆ ๆ–‡ไปถๅคนใ€‚ๅฝ“ๆ‚จๆ–ฐๅปบๆ–‡็ซ ๏ผˆๅณๆ–ฐๅปบmarkdownๆ–‡ไปถ๏ผ‰ๆ—ถ๏ผŒHexo ไผšๆ นๆฎ scaffold ๆฅๅปบ็ซ‹ๆ–‡ไปถใ€‚ source๏ผš่ต„ๆบๆ–‡ไปถๅคนๆ˜ฏๅญ˜ๆ”พ็”จๆˆท่ต„ๆบ๏ผˆๅณmarkdownๆ–‡ไปถ๏ผ‰็š„ๅœฐๆ–นใ€‚ themes๏ผšไธป้ข˜ ๆ–‡ไปถๅคนใ€‚Hexo ไผšๆ นๆฎไธป้ข˜ๆฅ็”Ÿๆˆ้™ๆ€้กต้ขใ€‚

3.ๆ–ฐๅปบๅšๅฎขๆ–‡็ซ  ๆ–ฐๅปบไธ€็ฏ‡ๆ–‡็ซ ๏ผˆๅณๆ–ฐๅปบmarkdownๆ–‡ไปถ๏ผ‰ๆŒ‡ไปค๏ผš

$ hexo new "ๆ–‡็ซ ๆ ‡้ข˜"

4.็”Ÿๆˆ้™ๆ€ๆ–‡ไปถ ๅฐ†ๆ–‡็ซ markdownๆ–‡ไปถๆŒ‰ๆŒ‡ๅฎšๆ ผๅผ็”Ÿๆˆ้™ๆ€็ฝ‘้กตๆ–‡ไปถ

$ hexo g  // g ่กจ็คบ generate ๏ผŒๆ˜ฏ็ฎ€ๅ†™

5.้ƒจ็ฝฒ็ฝ‘็ซ™ ๅณๅฐ†็”Ÿๆˆ็š„็ฝ‘้กตๆ–‡ไปถไธŠไผ ๅˆฐ็ฝ‘็ซ™ๆœๅŠกๅ™จ๏ผˆ่ฟ™้‡Œๆ˜ฏไธŠไผ ๅˆฐGithub๏ผ‰ใ€‚

ไธŠไผ ไน‹ๅ‰ๅฏไปฅๅ…ˆๅฏๅŠจๆœฌๅœฐๆœๅŠกๅ™จ๏ผˆๆŒ‡ไปค๏ผšhexo s ๏ผ‰๏ผŒๅœจๆœฌๅœฐ้ข„่งˆ็”Ÿๆˆ็š„็ฝ‘็ซ™ใ€‚

้ป˜่ฎคๆœฌๅœฐ้ข„่งˆ็ฝ‘ๅ€๏ผšhttp://localhost:4000/

$ hexo s  // s ่กจ็คบ server๏ผŒๆ˜ฏ็ฎ€ๅ†™

้ƒจ็ฝฒ็ฝ‘็ซ™ๆŒ‡ไปค๏ผš

$ hexo d  // d ่กจ็คบ deploy๏ผŒๆ˜ฏ็ฎ€ๅ†™

ๆณจๆ„๏ผŒๅฆ‚ๆžœๆŠฅ้”™๏ผš ERROR Deployer not found: git

้œ€่ฆๆˆ‘ไปฌๅ†ๅฎ‰่ฃ…ไธ€ไธชๆ’ไปถ๏ผš

$ sudo npm install hexo-deployer-git --save

ๅฎ‰่ฃ…ๅฎŒๆ’ไปถไน‹ๅŽๅ†ๆ‰ง่กŒไธ€ไธ‹ใ€hexo dใ€‘,ๅฎƒๅฐฑไผšๅผ€ๅง‹ๅฐ†publicๆ–‡ไปถๅคนไธ‹็š„ๆ–‡ไปถๅ…จ้ƒจไธŠไผ ๅˆฐไฝ ็š„gitHubไป“ๅบ“ไธญใ€‚

6.ๆธ…้™คๆ–‡ไปถ ๆธ…้™ค็ผ“ๅญ˜ๆ–‡ไปถ (db.json) ๅ’Œๅทฒ็”Ÿๆˆ็š„้™ๆ€ๆ–‡ไปถ (public็›ฎๅฝ•ไธ‹็š„ๆ‰€ๆœ‰ๆ–‡ไปถ)ใ€‚

ๆธ…้™คๆŒ‡ไปค๏ผš๏ผˆไธ€่ˆฌๆ˜ฏๆ›ดๆ”นไธ็”Ÿๆ•ˆๆ—ถไฝฟ็”จ๏ผ‰

$ hexo clean

debๅŒ…็š„่งฃๅŽ‹,ไฟฎๆ”น,้‡ๆ–ฐๆ‰“ๅŒ…ๆ–นๆณ•

็”จdpkgๅ‘ฝไปคๅˆถไฝœdebๅŒ…ๆ–นๆณ•ๆ€ป็ป“
ๅฆ‚ไฝ•ๅˆถไฝœDebๅŒ…ๅ’Œ็›ธๅบ”็š„่ฝฏไปถไป“ๅบ“๏ผŒๅ…ถๅฎž่ฟ™ไธชๅพˆ็ฎ€ๅ•ใ€‚่ฟ™้‡ŒๆŽจ่ไฝฟ็”จdpkgๆฅ่ฟ›่กŒdebๅŒ…็š„ๅˆ›ๅปบใ€็ผ–่พ‘ๅ’Œๅˆถไฝœใ€‚

้ฆ–ๅ…ˆไบ†่งฃไธ€ไธ‹debๅŒ…็š„ๆ–‡ไปถ็ป“ๆž„:

deb ่ฝฏไปถๅŒ…้‡Œ้ข็š„็ป“ๆž„๏ผšๅฎƒๅ…ทๆœ‰DEBIANๅ’Œ่ฝฏไปถๅ…ทไฝ“ๅฎ‰่ฃ…็›ฎๅฝ•๏ผˆๅฆ‚etc, usr, opt, tmp็ญ‰๏ผ‰ใ€‚ๅœจDEBIAN็›ฎๅฝ•ไธญ่ตท็ ๅ…ทๆœ‰controlๆ–‡ไปถ๏ผŒๅ…ถๆฌก่ฟ˜ๅฏ่ƒฝๅ…ทๆœ‰postinst(postinstallation)ใ€postrm(postremove)ใ€preinst(preinstallation)ใ€prerm(preremove)ใ€copyright (็‰ˆๆƒ๏ผ‰ใ€changlog ๏ผˆไฟฎ่ฎข่ฎฐๅฝ•๏ผ‰ๅ’Œconffiles็ญ‰ใ€‚

control: ่ฟ™ไธชๆ–‡ไปถไธป่ฆๆ่ฟฐ่ฝฏไปถๅŒ…็š„ๅ็งฐ๏ผˆPackage๏ผ‰๏ผŒ็‰ˆๆœฌ๏ผˆVersion๏ผ‰ไปฅๅŠๆ่ฟฐ๏ผˆDescription๏ผ‰็ญ‰๏ผŒๆ˜ฏdebๅŒ…ๅฟ…้กปๅ…ทๅค‡็š„ๆ่ฟฐๆ€งๆ–‡ไปถ๏ผŒไปฅไพฟไบŽ่ฝฏไปถ็š„ๅฎ‰่ฃ…็ฎก็†ๅ’Œ็ดขๅผ•ใ€‚ๅŒๆ—ถไธบไบ†่ƒฝๅฐ†่ฝฏไปถๅŒ…่ฟ›่กŒๅ……ๅˆ†็š„็ฎก็†๏ผŒๅฏ่ƒฝ่ฟ˜ๅ…ทๆœ‰ไปฅไธ‹ๅญ—ๆฎต:

Section: ่ฟ™ไธชๅญ—ๆฎต็”ณๆ˜Ž่ฝฏไปถ็š„็ฑปๅˆซ๏ผŒๅธธ่ง็š„ๆœ‰`utilsโ€™, `netโ€™, `mailโ€™, `textโ€™, `x11โ€ฒ ็ญ‰๏ผ›

Priority: ่ฟ™ไธชๅญ—ๆฎต็”ณๆ˜Ž่ฝฏไปถๅฏนไบŽ็ณป็ปŸ็š„้‡่ฆ็จ‹ๅบฆ๏ผŒๅฆ‚`requiredโ€™, `standardโ€™, `optionalโ€™, `extraโ€™ ็ญ‰๏ผ›

Essential: ่ฟ™ไธชๅญ—ๆฎต็”ณๆ˜Žๆ˜ฏๅฆๆ˜ฏ็ณป็ปŸๆœ€ๅŸบๆœฌ็š„่ฝฏไปถๅŒ…๏ผˆ้€‰้กนไธบyes/no๏ผ‰๏ผŒๅฆ‚ๆžœๆ˜ฏ็š„่ฏ๏ผŒ่ฟ™ๅฐฑ่กจๆ˜Ž่ฏฅ่ฝฏไปถๆ˜ฏ็ปดๆŒ็ณป็ปŸ็จณๅฎšๅ’Œๆญฃๅธธ่ฟ่กŒ็š„่ฝฏไปถๅŒ…๏ผŒไธๅ…่ฎธไปปไฝ•ๅฝขๅผ็š„ๅธ่ฝฝ๏ผˆ้™ค้ž่ฟ›่กŒๅผบๅˆถๆ€ง็š„ๅธ่ฝฝ๏ผ‰

Architecture:็”ณๆ˜Ž่ฝฏไปถๅŒ…็ป“ๆž„๏ผŒๅฆ‚ๅŸบไบŽ`i386โ€ฒ, โ€˜amd64โ€™,`m68kโ€™, `sparcโ€™, `alphaโ€™, `powerpcโ€™ ็ญ‰๏ผ›

Source: ่ฝฏไปถๅŒ…็š„ๆบไปฃ็ ๅ็งฐ๏ผ›

Depends: ่ฝฏไปถๆ‰€ไพ่ต–็š„ๅ…ถไป–่ฝฏไปถๅŒ…ๅ’Œๅบ“ๆ–‡ไปถใ€‚ๅฆ‚ๆžœๆ˜ฏไพ่ต–ๅคšไธช่ฝฏไปถๅŒ…ๅ’Œๅบ“ๆ–‡ไปถ๏ผŒๅฝผๆญคไน‹้—ด้‡‡็”จ้€—ๅท้š”ๅผ€๏ผ›

Pre-Depends: ่ฝฏไปถๅฎ‰่ฃ…ๅ‰ๅฟ…้กปๅฎ‰่ฃ…ใ€้…็ฝฎไพ่ต–ๆ€ง็š„่ฝฏไปถๅŒ…ๅ’Œๅบ“ๆ–‡ไปถ๏ผŒๅฎƒๅธธๅธธ็”จไบŽๅฟ…้กป็š„้ข„่ฟ่กŒ่„šๆœฌ้œ€ๆฑ‚๏ผ›

Recommends: ่ฟ™ไธชๅญ—ๆฎต่กจๆ˜ŽๆŽจ่็š„ๅฎ‰่ฃ…็š„ๅ…ถไป–่ฝฏไปถๅŒ…ๅ’Œๅบ“ๆ–‡ไปถ๏ผ›

Suggests: ๅปบ่ฎฎๅฎ‰่ฃ…็š„ๅ…ถไป–่ฝฏไปถๅŒ…ๅ’Œๅบ“ๆ–‡ไปถใ€‚


ๅฏนไบŽcontrol๏ผŒ่ฟ™้‡Œๆœ‰ไธ€ไธชๅฎŒๆ•ด็š„ไพ‹ๅญ:

Package: bioinfoserv-arb
Version: 2007_14_08
Section: BioInfoServ
Priority: optional
Depends: bioinfoserv-base-directories (>= 1.0-1), xviewg (>= 3.2p1.4), xfig (>= 1:3), libstdc++2.10-glibc2.2
Suggests: fig2ps
Architecture: i386
Installed-Size: 26104
Maintainer: Mingwei Liu <>
Provides: bioinfoserv-arb
Description: The ARB software is a graphically oriented package comprising various tools for sequence database handling and data analysis.
If you want to print your graphs you probably need to install the suggested fig2ps package.preinst: ่ฟ™ไธชๆ–‡ไปถๆ˜ฏ่ฝฏไปถๅฎ‰่ฃ…ๅ‰ๆ‰€่ฆ่ฟ›่กŒ็š„ๅทฅไฝœ๏ผŒๅทฅไฝœๆ‰ง่กŒไผšไพๆฎๅ…ถไธญ่„šๆœฌ่ฟ›่กŒ๏ผ›
postinst่ฟ™ไธชๆ–‡ไปถๅŒ…ๅซไบ†่ฝฏไปถๅœจ่ฟ›่กŒๆญฃๅธธ็›ฎๅฝ•ๆ–‡ไปถๆ‹ท่ดๅˆฐ็ณป็ปŸๅŽ๏ผŒๆ‰€้œ€่ฆๆ‰ง่กŒ็š„้…็ฝฎๅทฅไฝœใ€‚
prerm :่ฝฏไปถๅธ่ฝฝๅ‰้œ€่ฆๆ‰ง่กŒ็š„่„šๆœฌ
postrm: ่ฝฏไปถๅธ่ฝฝๅŽ้œ€่ฆๆ‰ง่กŒ็š„่„šๆœฌ็Žฐๅœจๆฅ็œ‹็œ‹ๅฆ‚ไฝ•ไฟฎ่ฎขไธ€ไธชๅทฒๆœ‰็š„debๅŒ…่ฝฏไปถ

=================================================================
debianๅˆถไฝœDEBๅŒ…(ๅœจrootๆƒ้™ไธ‹๏ผ‰๏ผŒๆ‰“ๅŒ…ไฝ็ฝฎ้šๆ„ใ€‚
#ๅปบ็ซ‹่ฆๆ‰“ๅŒ…่ฝฏไปถๆ–‡ไปถๅคน๏ผŒๅฆ‚
mkdir Cydia
cd   Cydia

#ไพๆฎ็จ‹ๅบ็š„ๅฎ‰่ฃ…่ทฏๅพ„ๅปบ็ซ‹ๆ–‡ไปถๅคน,ๅนถๅฐ†็›ธๅบ”็จ‹ๅบๆทปๅŠ ๅˆฐๆ–‡ไปถๅคนใ€‚ๅฆ‚
mkdir Applications
mkdir var/mobile/Documents (ๆธธๆˆ็ฑป้œ€่ฆ่ฟ™ไธช็›ฎๅฝ•๏ผŒๅ…ถไป–ไนŸๆœ‰ๅฏ่ƒฝ้œ€่ฆ๏ผ‰
mkdir *** (่ฆไพๆฎ็จ‹ๅบ่ฆๆฑ‚ๆฅๆทปๅŠ ๏ผ‰

#ๅปบ็ซ‹DEBIANๆ–‡ไปถๅคน
mkdir DEBIAN


#ๅœจDEBIAN็›ฎๅฝ•ไธ‹ๅˆ›ๅปบไธ€ไธชcontrolๆ–‡ไปถ,ๅนถๅŠ ๅ…ฅ็›ธๅ…ณๅ†…ๅฎนใ€‚
touch DEBIAN/control๏ผˆไนŸๅฏไปฅ็›ดๆŽฅไฝฟ็”จvi DEBIAN/control็ผ–่พ‘ไฟๅญ˜๏ผ‰
#็ผ–่พ‘control
vi DEBIAN/control

#็›ธๅ…ณๅ†…ๅฎน๏ผˆๆณจๆ„็ป“ๅฐพๅฟ…้กป็ฉบไธ€่กŒ๏ผ‰๏ผš
Package: soft ๏ผˆ็จ‹ๅบๅ็งฐ๏ผ‰
Version: 1.0.1 ๏ผˆ็‰ˆๆœฌ๏ผ‰
Section: utils ๏ผˆ็จ‹ๅบ็ฑปๅˆซ๏ผ‰
Architecture: iphoneos-arm   ๏ผˆ็จ‹ๅบๆ ผๅผ๏ผ‰
Installed-Size: 512   ๏ผˆๅคงๅฐ๏ผ‰
Maintainer: your <[email protected]>   ๏ผˆๆ‰“ๅŒ…ไบบๅ’Œ่”็ณปๆ–นๅผ๏ผ‰
Description: soft package ๏ผˆ็จ‹ๅบ่ฏดๆ˜Ž)
                                       ๏ผˆๆญคๅค„ๅฟ…้กป็ฉบไธ€่กŒๅ†็ป“ๆŸ๏ผ‰
ๆณจ๏ผšๆญคๆ–‡ไปถไนŸๅฏไปฅๅ…ˆๅœจ็”ต่„‘ไธŠ็ผ–่พ‘๏ผˆไฝฟ็”จๆ–‡ๆœฌ็ผ–่พ‘ๅฐฑๅฏไปฅ๏ผŒๅฎŒๆˆๅŽๅŽปๆŽ‰.txt),ๅ†ไผ ๅˆฐๆ‰“ๅŒ…็›ฎๅฝ•้‡Œใ€‚

#ๅœจDEBIAN้‡Œ่ฟ˜ๅฏไปฅๆ นๆฎ้œ€่ฆ่ฎพ็ฝฎ่„šๆœฌๆ–‡ไปถ
preinst
ๅœจDebๅŒ…ๆ–‡ไปถ่งฃๅŒ…ไน‹ๅ‰๏ผŒๅฐ†ไผš่ฟ่กŒ่ฏฅ่„šๆœฌใ€‚่ฎธๅคšโ€œpreinstโ€่„šๆœฌ็š„ไปปๅŠกๆ˜ฏๅœๆญขไฝœ็”จไบŽๅพ…ๅ‡็บง่ฝฏไปถๅŒ…็š„ๆœๅŠก๏ผŒ็›ดๅˆฐ่ฝฏไปถๅŒ…ๅฎ‰่ฃ…ๆˆ–ๅ‡็บงๅฎŒๆˆใ€‚

postinst
่ฏฅ่„šๆœฌ็š„ไธป่ฆไปปๅŠกๆ˜ฏๅฎŒๆˆๅฎ‰่ฃ…ๅŒ…ๆ—ถ็š„้…็ฝฎๅทฅไฝœใ€‚่ฎธๅคšโ€œpostinstโ€่„šๆœฌ่ดŸ่ดฃๆ‰ง่กŒๆœ‰ๅ…ณๅ‘ฝไปคไธบๆ–ฐๅฎ‰่ฃ…ๆˆ–ๅ‡็บง็š„่ฝฏไปถ้‡ๅฏๆœๅŠกใ€‚

prerm
่ฏฅ่„šๆœฌ่ดŸ่ดฃๅœๆญขไธŽ่ฝฏไปถๅŒ…็›ธๅ…ณ่”็š„daemonๆœๅŠกใ€‚ๅฎƒๅœจๅˆ ้™ค่ฝฏไปถๅŒ…ๅ…ณ่”ๆ–‡ไปถไน‹ๅ‰ๆ‰ง่กŒใ€‚

postrm
่ฏฅ่„šๆœฌ่ดŸ่ดฃไฟฎๆ”น่ฝฏไปถๅŒ…้“พๆŽฅๆˆ–ๆ–‡ไปถๅ…ณ่”๏ผŒๆˆ–ๅˆ ้™ค็”ฑๅฎƒๅˆ›ๅปบ็š„ๆ–‡ไปถใ€‚

#postinst ๅฆ‚๏ผš
#!/bin/sh
if [ "$1" = "configure" ]; then
/Applications/MobileLog.app/MobileLog -install
/bin/launchctl load -wF /System/Library/LaunchDaemons/com.iXtension.MobileLogDaemon.plist 
fi

#prerm ๅฆ‚๏ผš
#!/bin/sh
if [[ $1 == remove ]]; then
/Applications/MobileLog.app/MobileLog -uninstall
/bin/launchctl unload -wF /System/Library/LaunchDaemons/com.iXtension.MobileLogDaemon.plist 
fi

#ๅฆ‚ๆžœDEBIAN็›ฎๅฝ•ไธญๅซๆœ‰postinst ใ€prerm็ญ‰ๆ‰ง่กŒๆ–‡ไปถ
chmod -R 755 DEBIAN

#้€€ๅ‡บๆ‰“ๅŒ…่ฝฏไปถๆ–‡ไปถๅคน๏ผŒ็”ŸๆˆDEB
dpkg-deb --build Cydia
=====================================================================
ๆœ‰ๆ—ถๅ€™ๅฎ‰่ฃ…่‡ชๅทฑๆ‰“ๅŒ…็š„debๅŒ…ๆ—ถๆŠฅๅฆ‚ไธ‹้”™่ฏฏ๏ผš
Selecting previously deselected package initrd-deb.
(Reading database ... 71153 files and directories currently installed.)
Unpacking initrd-deb (from initrd-vstools_1.0_amd64.deb) ...
dpkg: error processing initrd-vstools_1.0_amd64.deb (--install):
trying to overwrite `/boot/initrd-vstools.img', which is also in package initrd-deb-2
dpkg-deb: subprocess paste killed by signal (Broken pipe)
Errors were encountered while processing:
initrd-vstools_1.0_amd64.deb
ไธป่ฆๆ„ๆ€ๆ˜ฏ่ฏด๏ผŒๅทฒ็ปๆœ‰ไธ€ไธชdebๅทฒ็ปๅฎ‰่ฃ…ไบ†็›ธๅŒ็š„ๆ–‡ไปถ๏ผŒๆ‰€ไปฅ้ป˜่ฎค้€€ๅ‡บๅฎ‰่ฃ…๏ผŒๅช่ฆๆŠŠๅŽŸๆฅๅฎ‰่ฃ…็š„ๆ–‡ไปถ็ป™ๅธ่ฝฝๆŽ‰๏ผŒๅ†ๆฌก่ฟ›่กŒๅฎ‰่ฃ…ๅฐฑๅฏไปฅไบ†ใ€‚

ไธ‹้ขไธบๅฎž่ทตๅ†…ๅฎน๏ผš

ๆ‰€ๆœ‰็š„็›ฎๅฝ•ไปฅๅŠๆ–‡ไปถ๏ผš

mydeb

|----DEBIAN

       |-------control
               |-------postinst

       |-------postrm

|----boot

       |----- initrd-vstools.img

ๅœจไปปๆ„็›ฎๅฝ•ไธ‹ๅˆ›ๅปบๅฆ‚ไธŠๆ‰€็คบ็š„็›ฎๅฝ•ไปฅๅŠๆ–‡ไปถ
# mkdir   -p /root/mydeb                          # ๅœจ่ฏฅ็›ฎๅฝ•ไธ‹ๅญ˜ๆ”พ็”ŸๆˆdebๅŒ…็š„ๆ–‡ไปถไปฅๅŠ็›ฎๅฝ•
# mkdir -p /root/mydeb/DEBIAN           #็›ฎๅฝ•ๅๅฟ…้กปๅคงๅ†™
# mkdir -p /root/mydeb/boot                   # ๅฐ†ๆ–‡ไปถๅฎ‰่ฃ…ๅˆฐ/boot็›ฎๅฝ•ไธ‹
# touch /root/mydeb/DEBIAN/control    # ๅฟ…้กป่ฆๆœ‰่ฏฅๆ–‡ไปถ
# touch /root/mydeb/DEBIAN/postinst # ่ฝฏไปถๅฎ‰่ฃ…ๅฎŒๅŽ๏ผŒๆ‰ง่กŒ่ฏฅShell่„šๆœฌ
# touch /root/mydeb/DEBIAN/postrm    # ่ฝฏไปถๅธ่ฝฝๅŽ๏ผŒๆ‰ง่กŒ่ฏฅShell่„šๆœฌ
# touch /root/mydeb/boot/initrd-vstools.img    # ๆ‰€่ฐ“็š„โ€œ่ฝฏไปถโ€็จ‹ๅบ๏ผŒ่ฟ™้‡Œๅฐฑๅชๆ˜ฏไธ€ไธช็ฉบๆ–‡ไปถ


controlๆ–‡ไปถๅ†…ๅฎน๏ผš
Package: my-deb   ๏ผˆ่ฝฏไปถๅ็งฐ๏ผŒไธญ้—ดไธ่ƒฝๆœ‰็ฉบๆ ผ๏ผ‰
Version: 1                  (่ฝฏไปถ็‰ˆๆœฌ)
Section: utils            ๏ผˆ่ฝฏไปถ็ฑปๅˆซ๏ผ‰
Priority: optional        ๏ผˆ่ฝฏไปถๅฏนไบŽ็ณป็ปŸ็š„้‡่ฆ็จ‹ๅบฆ๏ผ‰
Architecture: amd64   ๏ผˆ่ฝฏไปถๆ‰€ๆ”ฏๆŒ็š„ๅนณๅฐๆžถๆž„๏ผ‰
Maintainer: xxxxxx <> ๏ผˆๆ‰“ๅŒ…ไบบๅ’Œ่”็ณปๆ–นๅผ๏ผ‰
Description: my first deb ๏ผˆๅฏน่ฝฏไปถๆ‰€็š„ๆ่ฟฐ๏ผ‰

postinstๆ–‡ไปถๅ†…ๅฎน๏ผˆ ่ฝฏไปถๅฎ‰่ฃ…ๅฎŒๅŽ๏ผŒๆ‰ง่กŒ่ฏฅShell่„šๆœฌ๏ผŒไธ€่ˆฌ็”จๆฅ้…็ฝฎ่ฝฏไปถๆ‰ง่กŒ็Žฏๅขƒ๏ผŒๅฟ…้กปไปฅโ€œ#!/bin/shโ€ไธบ้ฆ–่กŒ๏ผŒ็„ถๅŽ็ป™่ฏฅ่„šๆœฌ่ต‹ไบˆๅฏๆ‰ง่กŒๆƒ้™๏ผšchmod +x postinst๏ผ‰๏ผš
#!/bin/sh
echo "my deb" > /root/mydeb.log

postrmๆ–‡ไปถๅ†…ๅฎน๏ผˆ ่ฝฏไปถๅธ่ฝฝๅŽ๏ผŒๆ‰ง่กŒ่ฏฅShell่„šๆœฌ๏ผŒไธ€่ˆฌไฝœไธบๆธ…็†ๆ”ถๅฐพๅทฅไฝœ๏ผŒๅฟ…้กปไปฅโ€œ#!/bin/shโ€ไธบ้ฆ–่กŒ๏ผŒ็„ถๅŽ็ป™่ฏฅ่„šๆœฌ่ต‹ไบˆๅฏๆ‰ง่กŒๆƒ้™๏ผšchmod +x postrm๏ผ‰๏ผš
#!/bin/sh
rm -rf /root/mydeb.log

็ป™mydeb็›ฎๅฝ•ๆ‰“ๅŒ…๏ผš
# dpkg -b   mydeb   mydeb-1.deb      # ็ฌฌไธ€ไธชๅ‚ๆ•ฐไธบๅฐ†่ฆๆ‰“ๅŒ…็š„็›ฎๅฝ•ๅ๏ผŒ
                                                            # ็ฌฌไบŒไธชๅ‚ๆ•ฐไธบ็”ŸๆˆๅŒ…็š„ๅ็งฐใ€‚

ๅฎ‰่ฃ…debๅŒ…๏ผš
# dpkg -i   mydeb-1.deb      # ๅฐ†initrd-vstools.imgๅคๅˆถๅˆฐ/boot็›ฎๅฝ•ไธ‹ๅŽ๏ผŒๆ‰ง่กŒpostinst๏ผŒ
                                            # postinst่„šๆœฌๅœจ/root็›ฎๅฝ•ไธ‹็”Ÿๆˆไธ€ไธชๅซๆœ‰"my deb"ๅญ—็ฌฆ็š„mydeb.logๆ–‡ไปถ

ๅธ่ฝฝdebๅŒ…๏ผš
# dpkg -r   my-deb      # ่ฟ™้‡Œ่ฆๅธ่ฝฝ็š„ๅŒ…ๅไธบcontrolๆ–‡ไปถPackageๅญ—ๆฎตๆ‰€ๅฎšไน‰็š„ my-deb ใ€‚
                                    # ๅฐ†/boot็›ฎๅฝ•ไธ‹initrd-vstools.imgๅˆ ้™คๅŽ๏ผŒๆ‰ง่กŒposrm๏ผŒ
                                    # postrm่„šๆœฌๅฐ†/root็›ฎๅฝ•ไธ‹็š„mydeb.logๆ–‡ไปถๅˆ ้™ค

ๆŸฅ็œ‹debๅŒ…ๆ˜ฏๅฆๅฎ‰่ฃ…๏ผš
# dpkg -s   my-deb      # ่ฟ™้‡Œ่ฆๅธ่ฝฝ็š„ๅŒ…ๅไธบcontrolๆ–‡ไปถPackageๅญ—ๆฎตๆ‰€ๅฎšไน‰็š„ my-deb

ๆŸฅ็œ‹debๅŒ…ๆ–‡ไปถๅ†…ๅฎน๏ผš
# dpkg   -c   mydeb-1.deb

ๆŸฅ็œ‹ๅฝ“ๅ‰็›ฎๅฝ•ๆŸไธชdebๅŒ…็š„ไฟกๆฏ๏ผš
# dpkg --info mydeb-1.deb

่งฃๅŽ‹debๅŒ…ไธญๆ‰€่ฆๅฎ‰่ฃ…็š„ๆ–‡ไปถ
# dpkg -x   mydeb-1.deb   mydeb-1    # ็ฌฌไธ€ไธชๅ‚ๆ•ฐไธบๆ‰€่ฆ่งฃๅŽ‹็š„debๅŒ…๏ผŒ่ฟ™้‡Œไธบ mydeb-1.deb
                                                             # ็ฌฌไบŒไธชๅ‚ๆ•ฐไธบๅฐ†debๅŒ…่งฃๅŽ‹ๅˆฐๆŒ‡ๅฎš็š„็›ฎๅฝ•๏ผŒ่ฟ™้‡Œไธบ mydeb-1

่งฃๅŽ‹debๅŒ…ไธญDEBIAN็›ฎๅฝ•ไธ‹็š„ๆ–‡ไปถ๏ผˆ่‡ณๅฐ‘ๅŒ…ๅซcontrolๆ–‡ไปถ๏ผ‰
# dpkg -e   mydeb-1.deb   mydeb-1/DEBIAN    # ็ฌฌไธ€ไธชๅ‚ๆ•ฐไธบๆ‰€่ฆ่งฃๅŽ‹็š„debๅŒ…๏ผŒ
                                                                           # ่ฟ™้‡Œไธบ mydeb-1.deb
                                                                          # ็ฌฌไบŒไธชๅ‚ๆ•ฐไธบๅฐ†debๅŒ…่งฃๅŽ‹ๅˆฐๆŒ‡ๅฎš็š„็›ฎๅฝ•๏ผŒ
                                                                           # ่ฟ™้‡Œไธบ mydeb-1/DEBIAN
                                                                        

macไธŠ ไฝฟ็”จdpkgๅ‘ฝไปค

1: ๅ…ˆ ๅฎ‰่ฃ… Macports

https://www.macports.org/install.php

2: ๅฎ‰่ฃ… dpkg

sudo port -f install dpkg
1ใ€ๅ‡†ๅค‡ๅทฅไฝœ๏ผš
    mkdir -p extract/DEBIAN
    mkdir build

2ใ€่งฃๅŒ…ๅ‘ฝไปคไธบ๏ผš
    #่งฃๅŽ‹ๅ‡บๅŒ…ไธญ็š„ๆ–‡ไปถๅˆฐextract็›ฎๅฝ•ไธ‹
    dpkg -X ../openssh-xxx.deb extract/
    #่งฃๅŽ‹ๅ‡บๅŒ…็š„ๆŽงๅˆถไฟกๆฏextract/DEBIAN/ไธ‹๏ผš
    dpkg -e ../openssh-xxx.deb extract/DEBIAN/
3ใ€ไฟฎๆ”นๆ–‡ไปถ:
    sed -i 's/PermitRootLogin yes/PermitRootLogin no/g' extract/etc/ssh/sshd_config
4ใ€ๅฏนไฟฎๆ”นๅŽ็š„ๅ†…ๅฎน้‡ๆ–ฐ่ฟ›่กŒๆ‰“ๅŒ…็”ŸๆˆdebๅŒ…
    dpkg-deb -b extract/ build/

fishhook

็›ธๅ…ณ่ต„ๆ–™

fishhookๆบ็ ๅˆ†ๆž

mach-oๆ ผๅผไป‹็ป

mach-oๅปถๆ—ถ็ป‘ๅฎš

ไปฅไธ‹ๆ˜ฏๅฎ˜ๆ–นๅ†…ๅฎน

fishhook is a very simple library that enables dynamically rebinding symbols in Mach-O binaries running on iOS in the simulator and on device. This provides functionality that is similar to using DYLD_INTERPOSE on OS X. At Facebook, we've found it useful as a way to hook calls in libSystem for debugging/tracing purposes (for example, auditing for double-close issues with file descriptors).

Usage

Once you add fishhook.h/fishhook.c to your project, you can rebind symbols as follows:

#import <dlfcn.h>

#import <UIKit/UIKit.h>

#import "AppDelegate.h"
#import "fishhook.h"

static int (*orig_close)(int);
static int (*orig_open)(const char *, int, ...);

int my_close(int fd) {
  printf("Calling real close(%d)\n", fd);
  return orig_close(fd);
}

int my_open(const char *path, int oflag, ...) {
  va_list ap = {0};
  mode_t mode = 0;

  if ((oflag & O_CREAT) != 0) {
    // mode only applies to O_CREAT
    va_start(ap, oflag);
    mode = va_arg(ap, int);
    va_end(ap);
    printf("Calling real open('%s', %d, %d)\n", path, oflag, mode);
    return orig_open(path, oflag, mode);
  } else {
    printf("Calling real open('%s', %d)\n", path, oflag);
    return orig_open(path, oflag, mode);
  }
}

int main(int argc, char * argv[])
{
  @autoreleasepool {
    rebind_symbols((struct rebinding[2]){{"close", my_close, (void *)&orig_close}, {"open", my_open, (void *)&orig_open}}, 2);

    // Open our own binary and print out first 4 bytes (which is the same
    // for all Mach-O binaries on a given architecture)
    int fd = open(argv[0], O_RDONLY);
    uint32_t magic_number = 0;
    read(fd, &magic_number, 4);
    printf("Mach-O Magic Number: %x \n", magic_number);
    close(fd);

    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
  }
}

Sample output

Calling real open('/var/mobile/Applications/161DA598-5B83-41F5-8A44-675491AF6A2C/Test.app/Test', 0)
Mach-O Magic Number: feedface 
Calling real close(3)
...

How it works

dyld binds lazy and non-lazy symbols by updating pointers in particular sections of the __DATA segment of a Mach-O binary. fishhook re-binds these symbols by determining the locations to update for each of the symbol names passed to rebind_symbols and then writing out the corresponding replacements.

For a given image, the __DATA segment may contain two sections that are relevant for dynamic symbol bindings: __nl_symbol_ptr and __la_symbol_ptr. __nl_symbol_ptr is an array of pointers to non-lazily bound data (these are bound at the time a library is loaded) and __la_symbol_ptr is an array of pointers to imported functions that is generally filled by a routine called dyld_stub_binder during the first call to that symbol (it's also possible to tell dyld to bind these at launch). In order to find the name of the symbol that corresponds to a particular location in one of these sections, we have to jump through several layers of indirection. For the two relevant sections, the section headers (struct sections from <mach-o/loader.h>) provide an offset (in the reserved1 field) into what is known as the indirect symbol table. The indirect symbol table, which is located in the __LINKEDIT segment of the binary, is just an array of indexes into the symbol table (also in __LINKEDIT) whose order is identical to that of the pointers in the non-lazy and lazy symbol sections. So, given struct section nl_symbol_ptr, the corresponding index in the symbol table of the first address in that section is indirect_symbol_table[nl_symbol_ptr->reserved1]. The symbol table itself is an array of struct nlists (see <mach-o/nlist.h>), and each nlist contains an index into the string table in __LINKEDIT which where the actual symbol names are stored. So, for each pointer __nl_symbol_ptr and __la_symbol_ptr, we are able to find the corresponding symbol and then the corresponding string to compare against the requested symbol names, and if there is a match, we replace the pointer in the section with the replacement.

The process of looking up the name of a given entry in the lazy or non-lazy pointer tables looks like this: Visual explanation

MachOView

ๆบ็ ๅœฐๅ€๏ผšhttps://github.com/gdbinit/MachOView

Mach-Oๆ ผๅผๅ…จ็งฐไธบMach Objectๆ–‡ไปถๆ ผๅผ็š„็ผฉๅ†™๏ผŒๆ˜ฏmacไธŠๅฏๆ‰ง่กŒๆ–‡ไปถ็š„ๆ ผๅผ๏ผŒ็ฑปไผผไบŽwindowsไธŠ็š„PEๆ ผๅผ (Portable Executable ), linuxไธŠ็š„elfๆ ผๅผ (Executable and Linking Format)ใ€‚

mach-oๆ–‡ไปถ็ฑปๅž‹ๅˆ†ไธบ๏ผš

1ใ€Executable๏ผšๅบ”็”จ็š„ไธป่ฆไบŒ่ฟ›ๅˆถ

2ใ€Dylib Library๏ผšๅŠจๆ€้“พๆŽฅๅบ“๏ผˆๅˆ็งฐDSOๆˆ–DLL๏ผ‰

3ใ€Static Library๏ผš้™ๆ€้“พๆŽฅๅบ“

4ใ€Bundle๏ผšไธ่ƒฝ่ขซ้“พๆŽฅ็š„Dylib๏ผŒๅช่ƒฝๅœจ่ฟ่กŒๆ—ถไฝฟ็”จdlopen( )ๅŠ ่ฝฝ๏ผŒๅฏๅฝ“ๅšmacOS็š„ๆ’ไปถ

5ใ€Relocatable Object File ๏ผšๅฏ้‡ๅฎšๅ‘ๆ–‡ไปถ็ฑปๅž‹

้‚ฃไป€ไนˆๅˆๆ˜ฏFatFile/FatBinary๏ผŸ

็ฎ€ๅ•ๆฅ่ฏด๏ผŒๅฐฑๆ˜ฏไธ€ไธช็”ฑไธๅŒ็š„็ผ–่ฏ‘ๆžถๆž„ๅŽ็š„Mach-Oไบง็‰ฉๆ‰€ๅˆๆˆ็š„้›†ๅˆไฝ“ใ€‚ไธ€ไธชๆžถๆž„็š„mach-Oๅช่ƒฝๅœจ็›ธๅŒๆžถๆž„็š„ๆœบๅ™จๆˆ–่€…ๆจกๆ‹Ÿๅ™จไธŠ็”จ๏ผŒไธบไบ†ๆ”ฏๆŒไธๅŒๆžถๆž„้œ€่ฆไธ€ไธช้›†ๅˆไฝ“ใ€‚

ไธ€ใ€ไฝฟ็”จๆ–นๅผ 1ใ€MachOViewๅทฅๅ…ทๆฆ‚่ฟฐ

MachOViewๅทฅๅ…ทๅฏMacๅนณๅฐไธญๅฏๆŸฅ็œ‹MachOๆ–‡ไปถๆ ผๅผไฟกๆฏ๏ผŒIOS็ณป็ปŸไธญๅฏๆ‰ง่กŒ็จ‹ๅบๅฑžไบŽMach-Oๆ–‡ไปถๆ ผๅผ๏ผŒๆœ‰ๅฟ…่ฆไป‹็ปๅฆ‚ไฝ•ๅˆฉ็”จๅทฅๅ…ทๅฟซ้€ŸๆŸฅ็œ‹Mach-Oๆ–‡ไปถๆ ผๅผใ€‚

็‚นๅ‡ปโ€œMachOViewโ€ไน‹ๅŽ๏ผŒไพฟๅœจMac็ณป็ปŸๅทฆไธŠ่ง’ๅ‡บ็ŽฐMachOViewๅทฅๅ…ท็š„ๆ“ไฝœ่œๅ•

ๅฐ†โ€œMachOViewโ€ๆ‹–ๅˆฐApplicationๆ–‡ไปถๅคน๏ผŒๅฐฑๅฏไปฅๅƒๅ…ถไป–็จ‹ๅบไธ€ๆ ทๅฏๅŠจไบ†

ไธ‹้ขไป‹็ปMachOViewๆ–‡ไปถๅŠŸ่ƒฝไฝฟ็”จใ€‚

2ใ€ๅŠ ่ฝฝMach-Oๆ–‡ไปถ ็‚นๅ‡ปMachOViewๅทฅๅ…ท็š„ไธป่œๅ•โ€œFileโ€ไธญ็š„โ€œOpenโ€้€‰้กนไพฟๅฏๅŠ ่ฝฝIOSๅนณๅฐๅฏๆ‰ง่กŒๆ–‡ไปถ๏ผŒๅฏนๅบ”ๅŠŸ่ƒฝๆŽฅๅ…ฅๅฆ‚ไธ‹ๆ‰€็คบ๏ผš

ไพ‹ๅฆ‚ๅŠ ่ฝฝๆ–‡ไปถๅไธบโ€œlibLDCPCircle.aโ€็š„้™ๆ€ๅบ“ๆ–‡ไปถ๏ผŒ

3ใ€ๆ–‡ไปถๅคดไฟกๆฏ MachOViewๅทฅๅ…ทๆˆๅŠŸๅŠ ่ฝฝMach-Oๆ–‡ไปถไน‹ๅŽ๏ผŒๆฏไธช.oๆ–‡ไปถๅฏนๅบ”ไธ€ไธช็ฑป็ผ–่ฏ‘ๅŽ็š„ๆ–‡ไปถ

ๅœจๅทฆ่พน็ช—ๅฃ็‚นๅ‡ปโ€œMach Headerโ€้€‰้กน๏ผŒๅฏไปฅ็œ‹ๅˆฐๆฏไธช็ฑป็š„cpuๆžถๆž„ไฟกๆฏใ€load commandsๆ•ฐ้‡ ใ€load commandssize ใ€file type็ญ‰ไฟกๆฏใ€‚

4ใ€ๆŸฅ็œ‹Fatๆ–‡ไปถ ๆˆ‘ไปฌๆ‰“ๅผ€ไธ€ไธชFatๆ–‡ไปถๅฏไปฅ็œ‹ๅˆฐ๏ผš

ๅฏไปฅ็œ‹ๅˆฐ๏ผŒfatๆ–‡ไปถๅชๆ˜ฏๅฏนๅ„็งๆžถๆž„ๆ–‡ไปถ็š„็ป„่ฃ…๏ผŒ็‚นๅผ€ โ€œFat Headerโ€ๅฏไปฅ็œ‹ๅˆฐๆ”ฏๆŒ็š„ๆžถๆž„๏ผŒๆ˜พ็คบ็š„ๆ”ฏๆŒARM_V7 ใ€ARM_V7S ใ€ARM_64 ใ€i386 ใ€ X86_64ใ€‚

็‚นๅผ€ๆฏไธ€ไธชStatic Library ๅฏไปฅ็œ‹ๅˆฐ๏ผŒๅ’Œๆฏไธ€ไธชๅ•็‹ฌ็š„Static Library็š„ไฟกๆฏไธ€ๆ ทใ€‚

ๅ‘ฝไปค๏ผš

lipo LoginSDK.a -thin armv7 -output arm/LoginSDK.a  ๅฐ†fatๆ–‡ไปถๆ‹†ๅˆ†ๅพ—ๅˆฐarmv7็ฑปๅž‹

lipo  -create    ibSyncSDKA.i386.a    libSyncSDK.arm7.a  -output  libSyncSDK.a  ๅˆๆˆไธ€ไธชi386ๅ’ŒarmV7ๆžถๆž„็š„fatๆ–‡ไปถ

OpenSSH

่ฟ™ไธชๅทฅๅ…ทๆ˜ฏ้€š่ฟ‡ๅ‘ฝไปค่กŒๅทฅๅ…ท่ฎฟ้—ฎ่‹นๆžœๆ‰‹ๆœบ๏ผŒๆ‰ง่กŒๅ‘ฝไปค่กŒ่„šๆœฌใ€‚ๅœจCydiaไธญๆœ็ดขopenssh๏ผŒๅฎ‰่ฃ…ใ€‚ๅ…ทไฝ“็”จๆณ•ๅฆ‚ไธ‹๏ผš 1ใ€ๆ‰“ๅผ€macไธ‹็š„terminal๏ผŒ่พ“ๅ…ฅๅ‘ฝไปคssh [email protected]๏ผˆ่ถŠ็‹ฑ่ฎพๅค‡ipๅœฐๅ€๏ผ‰ 2ใ€ๆŽฅไธ‹ๆฅไผšๆ็คบ่พ“ๅ…ฅ่ถ…็บง็ฎก็†ๅ‘˜่ดฆๅทๅฏ†็ ๏ผŒ้ป˜่ฎคๆ˜ฏalpine 3ใ€ๅ›ž่ฝฆ็กฎ่ฎค๏ผŒๅณๅฏroot็™ปๅฝ•่ฎพๅค‡ ไฝ ไนŸๅฏไปฅๅฐ†ไฝ mac็š„ๅ…ฌ้’ฅๅฏผๅ…ฅ่ฎพๅค‡็š„/var/root/.ssh/authorized_keysๆ–‡ไปถ๏ผŒ่ฟ™ๆ ทๅฐฑๅฏไปฅๅ…ๅฏ†็™ปๅฝ•rootไบ†ใ€‚

Reverse

Cycript

Cycriptๆ˜ฏๅคง็ฅžsaurikๅผ€ๅ‘็š„ไธ€ไธช้žๅธธๅผบๅคง็š„ๅทฅๅ…ท๏ผŒๅฏไปฅ่ฎฉๅผ€ๅ‘่€…ๅœจๅ‘ฝไปค่กŒไธ‹ๅ’Œๅบ”็”จไบคไบ’๏ผŒๅœจ่ฟ่กŒๆ—ถๆŸฅ็œ‹ๅ’Œไฟฎๆ”นๅบ”็”จใ€‚ๅฎƒๅฏไปฅๅธฎๅŠฉไฝ HOOKไธ€ไธชAppใ€‚Cycriptๆœ€ไธบ่ดดๅฟƒๅ’Œๅฎž็”จ็š„ๅŠŸ่ƒฝๆ˜ฏๅฎƒๅฏไปฅๅธฎๅŠฉๆˆ‘ไปฌ่ฝปๆพๆต‹่ฏ•ๅ‡ฝๆ•ฐๆ•ˆๆžœ๏ผŒๆ•ดไธช่ฟ‡็จ‹ๅฎ‰ๅ…จๆ— ๅ‰ฏไฝœ็”จ๏ผŒๆ•ˆๆžœๅๅˆ†ๆ˜พ่‘—๏ผŒๅฎžไนƒไธš็•Œ่‰ฏๅฟƒ๏ผ ๅฎ‰่ฃ…ๆ–นๅผ๏ผšๅœจCydiaไธญๆœ็ดขCycriptๅฎ‰่ฃ… ไฝฟ็”จๆ–นๆณ•๏ผš 1ใ€root็™ปๅฝ•่ถŠ็‹ฑ่ฎพๅค‡ 2ใ€cycript-p ไฝ ๆƒณ่ฆๆต‹่ฏ•็š„่ฟ›็จ‹ๅ 3ใ€้šไพฟ็Žฉ๏ผŒๅฎŒๅ…จๅ…ผๅฎนOC่ฏญๆณ•ๆฏ”ๅฆ‚cy# [#0x235b4fb1 hidden] Cycriptๆœ‰ๅ‡ ๆก้žๅธธๆœ‰็”จ็š„ๅ‘ฝไปค๏ผš choose๏ผšๅฆ‚ๆžœ็Ÿฅ้“ไธ€ไธช็ฑปๅฏน่ฑกๅญ˜ๅœจไบŽๅฝ“ๅ‰็š„่ฟ›็จ‹ไธญ๏ผŒๅดไธ็Ÿฅ้“ๅฎƒ็š„ๅœฐๅ€๏ผŒไธ่ƒฝ้€š่ฟ‡โ€œ#โ€ๆ“ไฝœ็ฌฆๆฅ่Žทๅ–ๅฎƒ๏ผŒๆญคๆ—ถๅฏไปฅไฝฟ็”จchooseๅ‘ฝไปค่Žทๅ–ๅˆฐ่ฏฅ็ฑป็š„ๆ‰€ๆœ‰ๅฏน่ฑก็š„ๅ†…ๅญ˜ๅœฐๅ€ ๆ‰“ๅฐไธ€ไธชๅฏน่ฑก็š„ๆ‰€ๆœ‰ๅฑžๆ€ง [obj _ivarDescription].toString() ๆ‰“ๅฐไธ€ไธชๅฏน่ฑก็š„ๆ‰€ๆœ‰ๆ–นๆณ•[obj _methodDescription].toString() ๅŠจๆ€ๆทปๅŠ ๅฑžๆ€ง objc_setAssociatedObject(obj,@โ€isAddโ€, [NSNumbernumberWithBool:YES], 0); ่Žทๅ–ๅŠจๆ€ๆทปๅŠ ็š„ๅฑžๆ€ง objc_getAssociatedObject(self, @โ€isAddโ€)

Reveal

Revealๆ˜ฏ็”ฑITTY BITTYๅ‡บๅ“็š„UIๅˆ†ๆžๅทฅๅ…ท๏ผŒๅฏไปฅ็›ด่ง‚ๅœฐๆŸฅ็œ‹App็š„UIๅธƒๅฑ€๏ผŒๆˆ‘ไปฌๅฏไปฅ็”จๆฅ็ ”็ฉถๅˆซไบบ็š„App็•Œ้ขๆ˜ฏๆ€Žไนˆๅš็š„๏ผŒๆœ‰ๅ“ชไบ›ๅ…ƒ็ด ใ€‚ๆ›ด้‡่ฆ็š„ๆ˜ฏ๏ผŒๅฏไปฅ็›ดๆŽฅๆ‰พๅˆฐไฝ ่ฆHOOK็š„้‚ฃไธชViewController๏ผŒ่ดผๆ–นไพฟไธ็”จ็žŽ็ŒซๆŠ“่€—ๅญไธ€ๆ ทๅˆฐๅค„ๅŽปๆ‰พๆ˜ฏๅ“ชไธชViewControllerไบ†ใ€‚ ๅฎ‰่ฃ…ๆ–นๆณ•๏ผš 1ใ€ไธ‹่ฝฝๅฎ‰่ฃ…Mac็‰ˆ็š„Reveal 2ใ€iOSๅฎ‰่ฃ…Reveal Loader๏ผŒๅœจCydiaไธญๆœ็ดขๅนถๅฎ‰่ฃ…Reveal Loader ๅœจๅฎ‰่ฃ…Reveal Loader็š„ๆ—ถๅ€™๏ผŒๅฎƒไผš่‡ชๅŠจไปŽReveal็š„ๅฎ˜็ฝ‘ไธ‹่ฝฝไธ€ไธชๅฟ…้กป็š„ๆ–‡ไปถlibReveal.dylibใ€‚ๅฆ‚ๆžœ็ฝ‘็ปœ็Šถๅ†ตไธๅคชๅฅฝ๏ผŒไธไธ€ๅฎš่ƒฝๅคŸๆˆๅŠŸไธ‹่ฝฝ่ฟ™ไธชdylibๆ–‡ไปถ๏ผŒๆ‰€ไปฅๅœจไธ‹่ฝฝๅฎŒReveal LoaderๅŽ๏ผŒๆฃ€ๆŸฅiOSไธŠ็š„โ€œ/Library/RHRevealLoader/โ€็›ฎๅฝ•ไธ‹ๆœ‰ๆฒกๆœ‰ไธ€ไธชๅไธบโ€œlibReveal.dylibโ€็š„ๆ–‡ไปถใ€‚ๅฆ‚ๆžœๆฒกๆœ‰ๅฐฑๆ‰“ๅผ€mac Reveal๏ผŒๅœจๅฎƒๆ ‡้ข˜ๆ ็š„โ€œHelpโ€้€‰้กนไธ‹๏ผŒ้€‰ไธญๅ…ถไธญ็š„โ€œShow Reveal Library in Finderโ€๏ผŒๆ‰พๅˆฐlibReveal.dylibๆ–‡ไปถ๏ผŒไฝฟ็”จscpๆ‹ท่ดๅˆฐ iOS็š„/Library/RHRevealLoader/็›ฎๅฝ•ไธ‹ใ€‚่‡ณๆญคRevealๅฎ‰่ฃ…ๅฎŒๆฏ•๏ผ

Dumpdecrypted

Dumpdecryptedๅฐฑๆ˜ฏ่‘—ๅ็š„็ ธๅฃณๅทฅๅ…ท๏ผŒๆ‰€่ฐ“็ ธๅฃณ๏ผŒๅฐฑๆ˜ฏๅฏน ipa ๆ–‡ไปถ่ฟ›่กŒ่งฃๅฏ†ใ€‚ๅ› ไธบๅœจไธŠไผ ๅˆฐ AppStore ไน‹ๅŽ๏ผŒAppStore่‡ชๅŠจ็ป™ๆ‰€ๆœ‰็š„ ipa ่ฟ›่กŒไบ†ๅŠ ๅฏ†ๅค„็†ใ€‚่€ŒๅฏนไบŽๅŠ ๅฏ†ๅŽ็š„ๆ–‡ไปถ๏ผŒ็›ดๆŽฅไฝฟ็”จ class-dump ๆ˜ฏๅพ—ไธๅˆฐไป€ไนˆไธœ่ฅฟ็š„๏ผŒๆˆ–่€…ๆ˜ฏ็ฉบๆ–‡ไปถ๏ผŒๆˆ–่€…ๆ˜ฏไธ€ๅ †ๅŠ ๅฏ†ๅŽ็š„ๆ–นๆณ•/็ฑปๅใ€‚ ไฝฟ็”จๆญฅ้ชคๅฆ‚ไธ‹๏ผš 1ใ€่ฎพๅค‡ไธญๆ‰“ๅผ€้œ€่ฆ็ ธๅฃณ็š„APPใ€‚ 2ใ€SSH่ฟžๆŽฅๅˆฐๆ‰‹ๆœบ๏ผŒๆ‰พๅˆฐipaๅŒ…็š„ไฝ็ฝฎๅนถ่ฎฐๅฝ•ไธ‹ๆฅใ€‚ 3ใ€Cycriptๅˆฐ่ฏฅipa็š„่ฟ›็จ‹๏ผŒๆ‰พๅˆฐApp็š„Documentsๆ–‡ไปถๅคนไฝ็ฝฎๅนถ่ฎฐๅฝ•ไธ‹ๆฅใ€‚ 4ใ€ๆ‹ท่ดdumpdecrypted.dylibๅˆฐApp็š„Documents ็š„็›ฎๅฝ•ใ€‚ 5ใ€ๆ‰ง่กŒ็ ธๅฃณๅŽ๏ผŒๅนถๆ‹ท่ดๅ‡บ็ ธๅฃณๅŽ็š„ไบŒ่ฟ›ๅˆถๆ–‡ไปถใ€‚ ๅ…ทไฝ“ๆ‰ง่กŒๅ‘ฝไปค๏ผš 1ใ€ssh [email protected] ๏ผˆiPๅœฐๅ€ไธบ่ถŠ็‹ฑ่ฎพๅค‡็š„iPๅœฐๅ€๏ผ‰ 2ใ€ ps -e ๏ผˆๆŸฅ็œ‹่ฟ›็จ‹๏ผŒๆŠŠ่ฟ›็จ‹ๅฏนๅบ”็š„ไบŒ่ฟ›ๅˆถๆ–‡ไปถๅœฐๅ€่ฎฐไธ‹ๆฅ๏ผ‰ 3ใ€cycript -p ่ฟ›็จ‹ๅ 4ใ€ [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0] ๏ผˆๆ‰พๅˆฐ็จ‹ๅบ็š„documents็›ฎๅฝ•๏ผ‰ 5ใ€scp ~/dumpdecrypted.dylib [email protected]:/var/mobile/Containers/Data/Application/XXXXXX/Documents 6ใ€DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/ Application/XXXXXX/xxx.app/xxx ็„ถๅŽๅฐฑไผš็”Ÿๆˆ.decrypted็š„ๆ–‡ไปถ๏ผŒ่ฟ™ไธชๅฐฑๆ˜ฏ็ ธๅฃณๅŽ็š„ๆ–‡ไปถใ€‚ๆŽฅไธ‹ๆฅๅ„็งๅทฅๅ…ท้ƒฝ้šไพฟไธŠไบ†class-dumpใ€IDAใ€Hopper Disassembler

class-dump

dump demo

$ class-dump -H /Users/xlsn0w/Desktop/Payload/JYLIM.app -o /Users/xlsn0w/Desktop/Header

class-dumpๅฐฑๆ˜ฏ็”จๆฅdumpไบŒ่ฟ›ๅˆถ่ฟ่กŒๆ–‡ไปถ้‡Œ้ข็š„classไฟกๆฏ็š„ๅทฅๅ…ทใ€‚ๅฎƒๅˆฉ็”จObjective-C่ฏญ่จ€็š„runtime็‰นๆ€ง๏ผŒๅฐ†ๅญ˜ๅ‚จๅœจMach-Oๆ–‡ไปถไธญ็š„ๅคดๆ–‡ไปถไฟกๆฏๆๅ–ๅ‡บๆฅ๏ผŒๅนถ็”Ÿๆˆๅฏนๅบ”็š„.hๆ–‡ไปถ๏ผŒ่ฟ™ไธชๅทฅๅ…ท้žๅธธๆœ‰็”จ๏ผŒๆœ‰ไบ†่ฟ™ไธชๅทฅๅ…ทๆˆ‘ไปฌๅฐฑๅƒๅ››็ปดไธ–็•Œ้‡Œ้ข็œ‹ไธ‰็ปด็‰ฉไฝ“๏ผŒไธ€ๅˆ‡ๆžถๆž„ๅฐฝๆ”ถ็œผๅบ•ใ€‚ class-dump็”จๆณ•๏ผš class-dump โ€“arch armv7 -s -S -H ไบŒ่ฟ›ๅˆถๆ–‡ไปถ่ทฏๅพ„ -o ๅคดๆ–‡ไปถไฟๅญ˜่ทฏๅพ„

IDA

IDAๆ˜ฏๅคงๅ้ผŽ้ผŽ็š„ๅ็ผ–่ฏ‘ๅทฅๅ…ท๏ผŒๅฎƒไนƒ้€†ๅ‘ๅทฅ็จ‹ไธญๆœ€่ดŸ็››ๅ็š„็ฅžๅ™จไน‹ไธ€ใ€‚ๆ”ฏๆŒWindowsใ€Linuxๅ’ŒMac OS X็š„ๅคšๅนณๅฐๅๆฑ‡็ผ–ๅ™จ/่ฐƒ่ฏ•ๅ™จ๏ผŒๅฎƒ็š„ๅŠŸ่ƒฝ้žๅธธๅผบๅคงใ€‚class-dumpๅฏไปฅๅธฎๆˆ‘ไปฌ็ฝ—ๅˆ—ๅ‡บ่ฆๅˆ†ๆž็š„ๅคดๆ–‡ไปถ๏ผŒIDA่ƒฝๅคŸๆทฑๅ…ฅๅ„ไธชๅ‡ฝๆ•ฐ็š„ๅ…ทไฝ“ๅฎž็Žฐ๏ผŒๆ— ่ฎบ็š„C๏ผŒC++๏ผŒOC็š„ๅ‡ฝๆ•ฐ้ƒฝๅฏไปฅๅ็ผ–่ฏ‘ๅ‡บๆฅใ€‚ไธ่ฟ‡ๅ็ผ–่ฏ‘ๅ‡บๆฅ็š„ๆ˜ฏๆฑ‡็ผ–ไปฃ็ ๏ผŒไฝ ้œ€่ฆๆœ‰ไธ€ๅฎš็š„ๆฑ‡็ผ–ๅŸบ็ก€ๆ‰่ƒฝ่ฏป็š„ๆ‡‚ใ€‚ IDAๅพˆๅƒๆœบๅ™จๆ€ง่ƒฝ๏ผˆๆˆ‘็š„ๆœบๅ™จ็ปๅธธๅกไฝไธๅŠจ๏ผ‰๏ผŒ่ฟ˜ๆœ‰ๅฆๅค–ไธ€ไธชๅ็ผ–่ฏ‘ๅทฅๅ…ทHopper๏ผŒๅฏนๆœบๅ™จๆ€ง่ƒฝ่ฆๆฑ‚ๆฒก้‚ฃไนˆ้ซ˜๏ผŒไนŸๅพˆๅฅฝ็”จ๏ผŒๆ€ไบบ่ถŠ่ดง็š„ๅˆฉๅ™จใ€‚

CydiaRepo

LLDB

LLDBๆ˜ฏ็”ฑ่‹นๆžœๅ‡บๅ“๏ผŒๅ†…็ฝฎไบŽXcodeไธญ็š„ๅŠจๆ€่ฐƒ่ฏ•ๅทฅๅ…ท๏ผŒๅฏไปฅ่ฐƒ่ฏ•Cใ€C++ใ€Objective-C๏ผŒ่ฟ˜ๅ…จ็›˜ๆ”ฏๆŒOSXใ€iOS๏ผŒไปฅๅŠiOSๆจกๆ‹Ÿๅ™จใ€‚LLDB่ฆ้…ๅˆdebugserverๆฅไฝฟ็”จใ€‚ๅธธ่ง็š„LLDBๅ‘ฝไปคๆœ‰๏ผš pๅ‘ฝไปค๏ผš้ฆ–ๅ…ˆpๆ˜ฏๆ‰“ๅฐ้žๅฏน่ฑก็š„ๅ€ผใ€‚ๅฆ‚ๆžœไฝฟ็”จๅฎƒๆ‰“ๅฐๅฏน่ฑก็š„่ฏ๏ผŒ้‚ฃไนˆๅฎƒไผšๆ‰“ๅฐๅ‡บๅฏน่ฑก็š„ๅœฐๅ€๏ผŒๅฆ‚ๆžœๆ‰“ๅฐ้žๅฏน่ฑกๅฎƒไธ€่ˆฌไผšๆ‰“ๅฐๅ‡บๅŸบๆœฌๅ˜้‡็ฑปๅž‹็š„ๅ€ผใ€‚ๅฝ“็„ถ็”จๅฎƒไนŸๅฏไปฅ็”ณๆ˜Žไธ€ไธชๅ˜้‡่ญฌๅฆ‚ p int a=10;๏ผˆๆณจlldbไฝฟ็”จa = 10; ๏ผˆๆณจlldbไฝฟ็”จๅœจๅ˜้‡ๅ‰ๆฅๅฃฐๆ˜Žไธบlldbๅ†…็š„ๅ‘ฝๅ็ฉบ้—ด็š„๏ผ‰ po ๅ‘ฝไปค๏ผšpo ๅ‘ฝไปคๆ˜ฏๆˆ‘ไปฌๆœ€ๅธธ็”จ็š„ๅ‘ฝไปคๅ› ไธบๅœจiosๅผ€ๅ‘ไธญ๏ผŒๆˆ‘ไปฌๆ—ถๅˆป้ขไธด็€ๅฏน่ฑก๏ผŒๆ‰€ไปฅๆˆ‘ไปฌๅœจ็ปๅคง้ƒจๅˆ†ๆ—ถๅ€™้ƒฝไผšไฝฟ็”จpoใ€‚้ฆ–ๅ…ˆpo่ฟ™ไธชๅ‘ฝไปคไผšๆ‰“ๅฐๅ‡บๅฏน่ฑก็š„descriptionๆ่ฟฐใ€‚ bt [all] ๆ‰“ๅฐ่ฐƒ็”จๅ †ๆ ˆ๏ผŒๆ˜ฏthread backtrace็š„็ฎ€ๅ†™๏ผŒๅŠ allๅฏๆ‰“ๅฐๆ‰€ๆœ‰thread็š„ๅ †ๆ ˆใ€‚ br l ๆ˜ฏbreakpoint list็š„็ฎ€ๅ†™๏ผŒๅˆ—ๅ‡บๆ‰€ๆœ‰็š„ๆ–ญ็‚น image list -o -f ๅˆ—ๅ‡บๆจกๅ—ๅ’ŒASLRๅ็งป๏ผŒไปฅๅŠๅ็งปๅŽ็š„ๅœฐๅ€๏ผŒๅฏไปฅ้€š่ฟ‡ๅ็งปๅŽ็š„ๅœฐๅ€-ASLRๅ็งปๆฅๅพ—ๅ‡บๆจกๅ—็š„ๅŸบๅœฐๅ€ใ€‚ b NSLog็ป™ๅ‡ฝๆ•ฐ่ฎพ็ฝฎๆ–ญ็‚น br s -a IDAไธญๅ็งปๅ‰็š„ๅœฐๅ€+ASLRๅ็งป้‡ ็ป™ๅ†…ๅญ˜ๅœฐๅ€่ฎพ็ฝฎๆ–ญ็‚น p (char *)$r1ๆ‰“ๅฐๅ‡ฝๆ•ฐๅ็งฐ br disใ€br enๅ’Œbr del่กจ็คบ็ฆ็”จใ€ๅฏ็”จๅ’Œๅˆ ้™คๆ–ญ็‚น nexti๏ผˆni๏ผ‰่ทณ่ฟ‡ไธ€่กŒ stepi๏ผˆsi๏ผ‰่ทณๅ…ฅๅ‡ฝๆ•ฐ c็ปง็ปญๆ‰ง่กŒ็›ดๅˆฐๆ–ญ็‚น register write r0 1ไฟฎๆ”นๅฏ„ๅญ˜ๅ™จ็š„ๅ€ผusbmuxdๅพˆๅคšไบบ้ƒฝๆ˜ฏ้€š่ฟ‡WiFi่ฟžๆŽฅไฝฟ็”จSSHๆœๅŠก็š„๏ผŒๅ› ไธบๆ— ็บฟ็ฝ‘็ปœ็š„ไธ็จณๅฎšๆ€งๅŠไผ ่พ“้€Ÿๅบฆ็š„้™ๅˆถ๏ผŒๅœจๅคๅˆถๆ–‡ไปถๆˆ–็”จLLDB่ฟœ็จ‹่ฐƒ่ฏ•ๆ—ถ๏ผŒiOS็š„ๅ“ๅบ”ๅพˆๆ…ข๏ผŒๆ•ˆ็Ž‡ไธ้ซ˜ใ€‚iOS่ถŠ็‹ฑ็คพๅŒบ็š„็ŸฅๅไบบๅฃซNikias Bassenๅผ€ๅ‘ไบ†ไธ€ๆฌพๅฏไปฅๆŠŠๆœฌๅœฐOSX/Windows็ซฏๅฃ่ฝฌๅ‘ๅˆฐ่ฟœ็จ‹iOS็ซฏๅฃ็š„ๅทฅๅ…ทusbmuxd๏ผŒไฝฟๆˆ‘ไปฌ่ƒฝๅคŸ้€š่ฟ‡USB่ฟžๆŽฅ็บฟsshๅˆฐiOSไธญ๏ผŒๅคงๅคงๅขžๅŠ ไบ†ssh่ฟžๆŽฅ็š„้€Ÿๅบฆ๏ผŒไนŸๆ–นไพฟไบ†้‚ฃไบ›ๆฒกๆœ‰WiFi็š„ๆœ‹ๅ‹ใ€‚ไฝฟ็”จusbmuxd่ƒฝๆžๅคงๆๅ‡ssh็š„้€Ÿๅบฆ๏ผŒ็”จLLDB่ฟœ็จ‹่ฟžๆŽฅdebugserver็š„ๆ—ถ้—ด่ขซ็ผฉ็Ÿญ่‡ณ15็ง’ไปฅๅ†…๏ผŒๅผบ็ƒˆๅปบ่ฎฎๅคงๅฎถๆŠŠusbmuxdไฝœไธบssh่ฟžๆŽฅ็š„้ฆ–้€‰ๆ–นๆกˆ

Theos

ไปฅไธŠ้ƒฝๆ˜ฏApp็š„ๅˆ†ๆžๅทฅๅ…ท๏ผŒ่€ŒTheosๆ˜ฏไธ€ไธช่ถŠ็‹ฑๅผ€ๅ‘ๅทฅๅ…ทๅŒ…๏ผˆๅ…ทไฝ“ๅ†™ไปฃ็ ๏ผ‰๏ผŒ็”ฑiOS่ถŠ็‹ฑ็•Œ็ŸฅๅไบบๅฃซDustin Howettๅผ€ๅ‘ๅนถๅˆ†ไบซๅˆฐGitHubไธŠใ€‚TheosไธŽๅ…ถไป–่ถŠ็‹ฑๅผ€ๅ‘ๅทฅๅ…ท็›ธๆฏ”๏ผŒๆœ€ๅคง็š„็‰น็‚นๅฐฑๆ˜ฏ็ฎ€ๅ•๏ผšไธ‹่ฝฝๅฎ‰่ฃ…็ฎ€ๅ•ใ€Logos่ฏญๆณ•็ฎ€ๅ•ใ€็ผ–่ฏ‘ๅ‘ๅธƒ็ฎ€ๅ•๏ผŒๅฏไปฅ่ฎฉไฝฟ็”จ่€…ๆŠŠ็ฒพๅŠ›้ƒฝๆ”พๅœจๅผ€ๅ‘ๅทฅไฝœไธŠๅŽปใ€‚ๅฐฑๆ˜ฏ่ฎฉไฝ ็œๅŽปไบ†็น็็š„ๅŽŸๅง‹ไปฃ็ ็ผ–ๅ†™๏ผŒ็ฎ€ๅŒ–ไบ†็ผ–่ฏ‘ๅ’Œๅฎ‰่ฃ…่ฟ‡็จ‹ใ€‚ๅŒๆ ทๆœ‰ไธ€ๆฌพๅทฅๅ…ทiOSOpenDevๆ˜ฏๆ•ดๅˆๅœจXcode้‡Œ็š„๏ผŒๅฏไปฅ็›ดๆŽฅๅœจXcodeไธญ้…็ฝฎๅผ€ๅ‘ใ€่ฟ่กŒ่ถŠ็‹ฑ็จ‹ๅบ๏ผŒไธ่ฟ‡iOSOpenDev็š„ๅฎ‰่ฃ…๏ผŒ่ฟ‡็จ‹็œŸ็š„ๆ˜ฏ่ฎฉไบบ่ฆๅ่ก€๏ผˆๆˆ‘ๆœ‰ไธ€ๅฐmacๆญปๆดป้ƒฝ่ฃ…ไธไธŠ๏ผ‰ใ€‚ ็”จๆณ•๏ผŒtheosๆœ‰ๅคš็งๆจกๆฟๅฏไปฅ้€‰ๆ‹ฉ๏ผŒๆœ€ๅธธ็”จ็š„ๅฐฑๆ˜ฏtweakๆ’ไปถไบ†๏ผš /opt/theos/bin/nic.plNIC 2.0 - New Instance Creator [1.] iphone/application [2.] iphone/library [3.] iphone/preference_bundle [4.] iphone/tool [5.] iphone/tweak ๆ‰“ๅŒ…็ผ–่ฏ‘ๅฎ‰่ฃ…๏ผŒ้œ€่ฆๆŒ‰็…งๅ›บๅฎšๆ ผๅผ็ผ–ๅ†™Makefileๆ–‡ไปถ๏ผŒ็„ถๅŽๆ‰ง่กŒๅ‘ฝไปค make package install๏ผŒ่‡ชๅŠจ็ผ–่ฏ‘ๆ‰“ๅŒ…ๅฎ‰่ฃ…ๅˆฐiOS่ฎพๅค‡ใ€‚ ๅฆ‚ๆžœไฝ ็”จ็š„ๆ˜ฏIOSOpenDevๅฐฑๆ›ด็ฎ€ๅ•ไบ†๏ผŒ้…็ฝฎๅฅฝiOS่ฎพๅค‡ipๅœฐๅ€๏ผŒ็›ดๆŽฅๆ‰ง่กŒproduct->Bulid for๏ผ>profiling๏ผŒ่‡ชๅŠจๆ‰“ๅŒ…ๅฎ‰่ฃ…ๅฅฝ

ไธ€ใ€ ๅฎ‰่ฃ…theos

1.ๆ‰“ๅผ€็ปˆ็ซฏ(terminal) 2.ๅ…ˆๅฎ‰่ฃ…Homebrew 3.brew install ldid

4.ไธ‹่ฝฝtheos ๅปบ่ฎฎๆœ€ๅฅฝไฝฟ็”จๅ‘ฝไปค่กŒ็š„ๆ–นๅผ่ฟ›่กŒไธ‹่ฝฝๅฎ‰่ฃ…๏ผŒๅ› ไธบtheosๅ†…ๅซๆœ‰ไธ€ไบ›ไพ่ต–ๆ–‡ไปถ git clone --recursive https://github.com/theos/theos.git $THEOS pS๏ผš$THEOSไธบ็Žฏๅขƒๅ˜้‡๏ผŒtheosไธ‹่ฝฝ็š„็›ฎๅฝ• ้…็ฝฎ็Žฏๅขƒๅ˜้‡็š„ๆ–นๆณ•ๅฆ‚ไธ‹->

$ ls -al /*ๆ‰พๅˆฐbash_profile */
$ vim .bash_profile /* ็ผ–่พ‘ๆ–‡ไปถ */
$ export THEOS=~/theos /* ๅŠ ๅ…ฅ็Žฏๅขƒๅ˜้‡ */
$ export PATH=~/theos/bin:$PATH /* ๅฆ‚ๆžœไธๅŠ ๅ…ฅ่ฟ™่กŒ๏ผŒtheos็š„ๅ‘ฝไปคไผšๆ— ๆ•ˆใ€‚ */ /** $PATH ๅƒไธ‡ไธ่ฆๅฟ˜่ฎฐๅ†™ๆˆ–่€…ๅ†™้”™๏ผŒไธ็„ถๆ‰€ๆœ‰็š„ๅ‘ฝไปค้ƒฝ็”จไธไบ†ไบ†ใ€‚ๅฆ‚ๆžœ็œŸ่ฟ™ๆ ทไบ†่ฏทๆ‰“ๅผ€่ฟ™ไธช้“พๆŽฅๆŒ‰ๆญฅ้ชค่ฟ›่กŒhttps://zhidao.baidu.com/question/1755826278714933228.html **/
$ :wq  /* ไฟๅญ˜้€€ๅ‡บ */
$ source .bash_profile /* ไฝฟๆ–ฐๆทปๅŠ ็š„็Žฏๅขƒๅ˜้‡็ซ‹ๅณ็”Ÿๆ•ˆ */

ๆ–ฐๅปบ้กน็›ฎ

$ nic.pl

NIC 2.0 - New Instance Creator
------------------------------
[1.] iphone/activator_event
[2.] iphone/application_modern
[3.] iphone/application_swift
[4.] iphone/flipswitch_switch
[5.] iphone/framework
[6.] iphone/library
[7.] iphone/preference_bundle_modern
[8.] iphone/tool
[9.] iphone/tool_swift
[10.] iphone/tweak
[11.] iphone/xpc_service
Choose a Template (required): 10
Project Name (required): XLsn0wtweak
Package Name [com.yourcompany.xlsn0wtweak]: com.xlsn0w.xlsn0wtweak
Author/Maintainer Name [Mac]: XLsn0w
[iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]: 
[iphone/tweak] List of applications to terminate upon installation (space-separated, '-' for none) [SpringBoard]: 
Instantiating iphone/tweak in xlsn0wtweak/...
Done.


 ****** How to Hook with Logos ******
 
 
Hooks are written with syntax similar to that of an Objective-C @implementation.
You don't need to #include <substrate.h>, it will be done automatically, as will
the generation of a class list and an automatic constructor.

%hook ClassName

// Hooking a class method
+ (id)sharedInstance {
return %orig;
}

// Hooking an instance method with an argument.
- (void)messageName:(int)argument {
%log; // Write a message about this call, including its class, name and arguments, to the system log.

%orig; // Call through to the original function with its original arguments.
%orig(nil); // Call through to the original function with a custom argument.

// If you use %orig(), you MUST supply all arguments (except for self and _cmd, the automatically generated ones.)
}

// Hooking an instance method with no arguments.
- (id)noArguments {
%log;
id awesome = %orig;
[awesome doSomethingElse];

return awesome;
}

// Always make sure you clean up after yourself; Not doing so could have grave consequences!
%end


Cydiapple

Cycript

ๅฎ˜็ฝ‘๏ผšhttp://www.cycript.org/

่ถŠ็‹ฑ็š„่ฎพๅค‡๏ผŒๅœจcydiaไธญๅฎ‰่ฃ…่ฟ™ไธชๆ’ไปถใ€‚

2ใ€่ฎพๅค‡็Žฏๅขƒ

mac , iOS่ฎพๅค‡๏ผˆๅทฒ็ป่ถŠ็‹ฑ๏ผ‰

้ฆ–ๅ…ˆ๏ผŒๅœจๆ‰‹ๆœบไธŠๅฎ‰่ฃ…openssh๏ผŒ ๅฎ‰่ฃ…ๆ–นๅผ๏ผšcydiaใ€‚ๅฝ“็„ถ๏ผŒไฝ ไนŸๅฏๆ˜ฏๅŽปๅฎ˜็ฝ‘ไธ‹่ฝฝๅŒ…๏ผŒ็„ถๅŽๅœจๅฐ†ๅ…ถๆ‰“ๅŒ…ๆˆ.debๆ ผๅผ๏ผŒๅ†ๆ‹ทๅ…ฅiPhoneไธญใ€‚

MacไธŽ iPhoneๆŽฅๅœจไบ†ๅŒไธ€ไธชๅฑ€ๅŸŸ็ฝ‘ไธ‹

3ใ€ ็ฎ€ๅ•ไฝฟ็”จ

ไฝฟ็”จcycript๏ผŒๅฏๅฎž็Žฐ็ฎ€ๅ•็š„่ฟ›็จ‹ๆณจๅ…ฅใ€‚ๅฝ“็„ถ๏ผŒ่ฟ˜ๅฏไปฅ็”จไฝœๅ…ถไป–ๆ–น้ข๏ผŒๅ› ไธบๅ…ถๅฎžๆ—ถๆ€งๅผบใ€‚่ฟ™้‡Œ๏ผŒๆˆ‘ๅฐฑๅฎž็Žฐไบ†็ฎ€ๅ•็š„่ฟ›็จ‹ๆณจๅ…ฅใ€‚

4ใ€ๅฎž็Žฐ่ฟ‡็จ‹๏ผš

Aใ€ๅœจMacไธ‹ไฝฟ็”จ็ปˆ็ซฏ็™ปๅฝ•ๅˆฐiPhoneไธŠ๏ผŒ้ป˜่ฎคๅฏ†็ ๆ˜ฏ๏ผšalpine๏ผŒไฝฟ็”จๅ‘ฝไปค๏ผšssh [email protected]

ๅฝ“็„ถ๏ผŒไฝ ไนŸๅฏไปฅๅœจ่‡ชๅทฑ็š„iPhoneไธŠ่ฃ… MTerminal ๆ’ไปถใ€‚ ๅฆ‚ไธ‹ๅ›พ MTerminal

Bใ€ๅ›žๅˆฐไธป้ข˜๏ผŒ็ปง็ปญๅœจ็ปˆ็ซฏ้”ฎๅ…ฅๅ‘ฝไปค ps -e | grep SpringBoard, ๆŸฅๆ‰พ ่ฟ›็จ‹id

Cใ€ๆ‰พๅˆฐID ๅŽ๏ผŒๅฐฑๅฏไปฅ็”จcycriptๅฎž็Žฐๆณจๅ…ฅไบ†๏ผŒ้”ฎๅ…ฅๅ‘ฝไปคๅฆ‚ไธ‹๏ผšcycript -p 14823

Dใ€ๅฎŒๆˆๆณจๅ…ฅๅŽ๏ผŒๆŽฅ็€้”ฎๅ…ฅไธ‹้ข็š„ๅ‘ฝไปค๏ผŒ็„ถๅŽๅ›ž่ฝฆ๏ผŒๅ†็œ‹็œ‹่‡ชๅทฑ็š„iPhoneๅงใ€‚

alertView = [[[UIAlertView alloc] initWithTitle:@"title" message:@"message" delegate:il cancelButtonTitle:@"ok" otherButtonTitles:nil] show]

ๆˆ‘่ฟ™้‡Œๆณจๅ…ฅ็š„่ฟ›็จ‹ๆ˜ฏ SpringBoard ใ€‚ ็ฎ€ๅ•็š„่ฟ›็จ‹ๆณจๅ…ฅ๏ผŒๅชๆ˜ฏcycriptๅŠŸ่ƒฝ็š„ๅ†ฐๅฑฑไธ€่ง’ไธญ็š„ไธ€ๅฐ็‚น๏ผŒๅฎƒ่ฟ˜ๆœ‰ๅพˆๅคšๅผบๅคง็š„ๅŠŸ่ƒฝ๏ผŒ็œ‹็œ‹ๅฎ˜็ฝ‘็š„ๆ–‡ๆกฃๅงใ€‚่ถ…่ฏฆ็ป†

ๆ–‡ๆกฃไผ ้€้—จ๏ผšhttp://www.cycript.org/manual/

Theos

Gitไป“ๅบ“ๅœฐๅ€๏ผšhttps://github.com/theos/theos by Github@DHowett

ๆ›ดๆ–ฐๆจก็‰ˆ๏ผšhttps://github.com/DHowett/theos-nic-templates

lidi: http://joedj.net/ldid

dpkg-deb๏ผšhttps://github.com/DHowett/dm.pl

ๅฎ‰่ฃ…

  • ไธ‹่ฝฝtheosๅนถๅฎ‰่ฃ…ๅˆฐ /opt/theos
  • ้…็ฝฎ็Žฏๅขƒๅ˜้‡ cd ~ -> export THEOS=/opt/theos
  • ไธ‹่ฝฝldidๅˆฐ/opt/theos/bin ไฟฎๆ”นๆƒ้™ sudo chmod 777 /opt/theos/bin/ldid
  • ไธ‹่ฝฝdm.pl้‡ๅ‘ฝๅไธบdpkg-debๅˆฐ/opt/theos/bin ไฟฎๆ”นๆƒ้™ sudo chmod 777 /opt/theos/bin/dpkg-deb
  • ๆ›ดๆ–ฐๆจก็‰ˆjarไธ‹่ฝฝๆ‹ท่ด่‡ณopt/theos/templates/iphone/๏ผŒๆณจๆ„ๅŽป้‡

ๅˆ›ๅปบๅทฅ็จ‹

็ปˆ็ซฏ่ฟ่กŒ $THEOS/bin/nic.pl

NIC 2.0 - New Instance Creator
------------------------------
  [1.] iphone/activator_event
  [2.] iphone/application_modern
  [3.] iphone/cydget
  [4.] iphone/flipswitch_switch
  [5.] iphone/framework
  [6.] iphone/ios7_notification_center_widget
  [7.] iphone/library
  [8.] iphone/notification_center_widget
  [9.] iphone/preference_bundle_modern
  [10.] iphone/sbsettingstoggle
  [11.] iphone/tool
  [12.] iphone/tweak
  [13.] iphone/xpc_service
Choose a Template (required): 

Logos่ฏญๆณ•

http://iphonedevwiki.net/index.php/Logos

ๆ–ฐๅปบMonkeyๅทฅ็จ‹ๆ—ถ,MonkeyDevๅทฒ็ปๅฐ†libsubstrate.dylibๅบ“ๅ’ŒRevealServer.frameworkๅบ“ๆณจๅ…ฅ่ฟ›ๅŽปไบ†๏ผŒๆœ‰ไบ†libsubstrate.dylibๅบ“ๅฐฑ่ƒฝๅ†™Logos่ฏญๆณ•

Logos่ฏญๆณ• ๅŠŸ่ƒฝ่งฃ้‡Š ไบ‹ไพ‹

%hook    ้œ€่ฆhookๅ“ชไธช็ฑป    %hook Classname
%end    ไปฃ็ ๅ—็ป“ๆŸๆ ‡่ฎฐ    
%group    ๅˆ†็ป„    %group Groupname
%new    ๆทปๅŠ ๆ–ฐๆ–นๆณ•    %new(signature)
%ctor    ๆž„้€ ๅ‡ฝๆ•ฐ    %ctor { โ€ฆ }
%dtor    ๆžๆž„ๅ‡ฝๆ•ฐ    %dtor { โ€ฆ }
%log    ่พ“ๅ‡บๆ‰“ๅฐ    %log; %log([(
%orig    ไฟๆŒๅŽŸๆœ‰ๆ–นๆณ•    %orig๏ผ›%orig(arg1, โ€ฆ)๏ผ›
%c        %c([+/-]Class)๏ผ›

1.%hook %end

ๆŒ‡ๅฎš้œ€่ฆhook็š„class,ๅฟ…้กปไปฅ๏ผ…end็ป“ๅฐพใ€‚

// hook SpringBoard็ฑป้‡Œ้ข็š„_menuButtonDownๅ‡ฝๆ•ฐ,ๅ…ˆๆ‰“ๅฐไธ€ๅฅ่ฏ,ๅ†ไน‹ๅญ้‚ฃไธชๅ‡ฝๆ•ฐๅŽŸๅง‹็š„ๆ“ไฝœ %hook SpringBorad

- (void)_menuButtonDown:(id)down
{
NSLog(@"111111");
%orig; // ่ฐƒ็”จๅŽŸๅง‹็š„_menuButtonDownๅ‡ฝๆ•ฐ
}
%end

2.%group

่ฏฅๆŒ‡ไปค็”จไบŽๅฐ†%hookๅˆ†็ป„๏ผŒไพฟไบŽไปฃ็ ็ฎก็†ๅŠๆŒ‰ๆกไปถๅˆๅง‹ๅŒ–ๅˆ†็ป„๏ผŒๅฟ…้กปไปฅ%end็ป“ๅฐพใ€‚ ไธ€ไธช๏ผ…groupๅฏไปฅๅŒ…ๅซๅคšไธช%hook,ๆ‰€ๆœ‰ไธๅฑžไบŽๆŸไธช่‡ชๅฎšไน‰group็š„๏ผ…hookไผš่ขซ้šๅผๅฝ’็ฑปๅˆฐ๏ผ…group_ungroupedไธญใ€‚

%group iOS8
%hook IOS8_SPECIFIC_CLASS
// your code here
%end // end hook
%end // end group ios8

%group iOS9
%hook IOS9_SPECIFIC_CLASS
// your code here
%end // end hook
%end // end group ios9

%ctor {
if (kCFCoreFoundationVersionNumber > 1200) {
%init(iOS9);
} else {
%init(iOS8);
}
}

3.%new

ๅœจ%hookๅ†…้ƒจไฝฟ็”จ๏ผŒ็ป™ไธ€ไธช็Žฐๆœ‰classๆทปๅŠ ๆ–ฐๅ‡ฝๆ•ฐ๏ผŒๅŠŸ่ƒฝไธŽclass_addMethod็›ธๅŒ. ๆณจ๏ผš Objective-C็š„categoryไธŽclass_addMethod็š„ๅŒบๅˆซ๏ผš ๅ‰่€…ๆ˜ฏ้™ๆ€็š„่€ŒๅŽ่€…ๆ˜ฏๅŠจๆ€็š„ใ€‚ไฝฟ็”จ%newๆทปๅŠ ,่€Œไธ้œ€่ฆๅ‘.hๆ–‡ไปถไธญๆทปๅŠ ๅ‡ฝๆ•ฐๅฃฐๆ˜Ž,ๅฆ‚ๆžœไฝฟ็”จcategory,ๅฏ่ƒฝไธŽ้‡ๅˆฐ่ฟ™ๆ ท้‚ฃๆ ท็š„้”™่ฏฏ.

%hook SpringBoard
%new
- (void)addNewMethod
{
NSLog(@"ๅŠจๆ€ๆทปๅŠ ไธ€ไธชๆ–นๆณ•ๅˆฐSpringBoard");
}
%end

4.%ctor

tweak็š„constructor,ๅฎŒๆˆๅˆๅง‹ๅŒ–ๅทฅไฝœ๏ผ›ๅฆ‚ๆžœไธๆ˜พ็คบๅฎšไน‰๏ผŒTheosไผš่‡ชๅŠจ็”Ÿๆˆไธ€ไธช%ctor,ๅนถๅœจๅ…ถไธญ่ฐƒ็”จ%init(_ungrouped)ใ€‚%ctorไธ€่ˆฌๅฏไปฅ็”จๆฅๅˆๅง‹ๅŒ–%group,ไปฅๅŠ่ฟ›่กŒMSHookFunction็ญ‰ๆ“ไฝœ,ๅฆ‚ไธ‹:

#ifndef KCFCoreFoundationVersionNumber_iOS_8_0
#define KCFCoreFoundationVersionNumber_iOS_8_0      1140.10
#endif

%ctor
{
%init;

if (KCFCoreFoundationVersionNumber >= KCFCoreFoundationVersionNumber_iOS_7_0 && KCFCoreFoundationVersionNumber > KCFCoreFoundationVersionNumber_iOS_8_0)
%init(iOS7Hook);
if (KCFCoreFoundationVersionNumber >= KCFCoreFoundationVersionNumber_iOS_8_0)
%init(iOS8Hook);
MSHookFunction((void *)&AudioServicesPlaySystemSound,(void *)&replaced_AudioServerPlaySystemSound,(void **)&orginal_AudioServicesPlaySystemSound);
}

5.%dtor

Generate an anonymous deconstructor (of default priority).

%dtor { โ€ฆ } 6.%log

่ฏฅๆŒ‡ไปคๅœจ%hookๅ†…้ƒจไฝฟ็”จ๏ผŒๅฐ†ๅ‡ฝๆ•ฐ็š„็ฑปๅใ€ๅ‚ๆ•ฐ็ญ‰ไฟกๆฏๅ†™ๅ…ฅsyslog,ๅฏไปฅ๏ผ…log([(),โ€ฆ..])็š„ๆ ผๅผ่ฟฝๅŠ ๅ…ถไป–ๆ‰“ๅฐไฟกๆฏใ€‚

%hook SpringBorad
- (void)_menuButtonDown:(id)down
{
%log((NSString *)@"iosre",(NSString *)@"Debug");
%orig; // ่ฐƒ็”จๅŽŸๅง‹็š„_menuButtonDownๆ–นๆณ•
}
%end

6.%orig

่ฏฅๆŒ‡ไปคๅœจ%hookๅ†…้ƒจไฝฟ็”จ๏ผŒๆ‰ง่กŒ่ขซhook็š„ๅ‡ฝๆ•ฐ็š„ๅŽŸๅง‹ไปฃ็ ๏ผ›ไนŸๅฏไปฅ็”จ๏ผ…origๆ›ดๆ”นๅŽŸๅง‹ๅ‡ฝๆ•ฐ็š„ๅ‚ๆ•ฐใ€‚

%hook SpringBorad
- (void)setCustomSubtitleText:(id)arg1 withColor:   (id)arg2
{
%orig(@"change arg2",arg2);// ๅฐ†arg2็š„ๅ‚ๆ•ฐไฟฎ ๆ”นไธบ"change arg2"
}
%end

7.%init

่ฏฅๆŒ‡ไปค็”จไบŽๅˆๅง‹ๅŒ–ๆŸไธช๏ผ…group๏ผŒๅฟ…้กปๅœจ%hookๆˆ–๏ผ…ctorๅ†…่ฐƒ็”จ๏ผ›ๅฆ‚ๆžœๅธฆๅ‚ๆ•ฐ๏ผŒๅˆ™ๅˆๅง‹ๅŒ–ๆŒ‡ๅฎš็š„group๏ผŒๅฆ‚ๆžœไธๅธฆๅ‚ๆ•ฐ๏ผŒๅˆ™ๅˆๅง‹ๅŒ–_ungrouped. ๆณจ๏ผš ๅˆ‡่ฎฐ๏ผŒๅชๆœ‰่ฐƒ็”จไบ†๏ผ…init,ๅฏนๅบ”็š„%groupๆ‰่ƒฝ่ตทไฝœ็”จ๏ผ

8.%c

่ฏฅๆŒ‡ไปค็š„ไฝœ็”จ็ญ‰ๅŒไบŽobjc_getClassๆˆ–NSClassFromString,ๅณๅŠจๆ€่Žทๅ–ไธ€ไธช็ฑป็š„ๅฎšไน‰๏ผŒๅœจ%hookๆˆ–๏ผ…ctorๅ†…ไฝฟ็”จ ใ€‚

Class-dump

Githubๅœฐๅ€๏ผš https://github.com/nygard/class-dump

ไธป้กต๏ผšhttp://stevenygard.com/projects/class-dump

ไธ‹่ฝฝๅนถๆ‰“ๅผ€ๅฎ‰่ฃ…ๅŒ…๏ผˆ็‰ˆๆœฌๅฏ่ƒฝไผš้šๆ—ถๆ›ดๆ–ฐ๏ผ‰ ๅฐ†class-dumpๅฏๆ‰ง่กŒๆ–‡ไปถๆ”พๅˆฐ/usr/binไธ‹ๆˆ–่€…/usr/local/bin

class-dump 3.5 (64 bit)
Usage: class-dump [options] <mach-o-file>

where options are:
-a             ๆ˜พ็คบๅฎžไพ‹ๅ˜้‡็š„ๅ็งป
-A             ๆ˜พ็คบๅฎž็Žฐๅœฐๅ€
--arch <arch>  ้€‰ๆ‹ฉ้€š็”จไบŒ่ฟ›ๅˆถ็‰นๅฎš็š„ๆžถๆž„(PPC,PPC64,ๆ˜ฏi386,x86_64๏ผ‰
-C <regex>     ๅชๆ˜พ็คบ็ฑปๅŒน้…็š„ๆญฃๅˆ™่กจ่พพๅผ
-f <str>       ๆ‰พๅˆฐๆ–นๆณ•ๅๅญ—็ฌฆไธฒ
-H             ๅœจๅฝ“ๅ‰่ทฏๅพ„ไธ‹ๅฏผๅ‡บๅคดๆ–‡ไปถ๏ผŒๆˆ–่€…้€š่ฟ‡-oๆŒ‡ๅฎš่ทฏๅพ„
-I             ๆŽ’ๅบ็ฑป๏ผŒ็ฑปๅˆซ๏ผŒไปฅๅŠ้€š่ฟ‡็ปงๆ‰ฟๅ่ฎฎ ps:ๆญคๅ‚ๆ•ฐๅฐ†่ฆ†็›–-s
-o <dir>       -Hๅฏผๅ‡บๅคดๆ–‡ไปถ็š„ๆŒ‡ๅฎšไฟๅญ˜่ทฏๅพ„
-r             ้€’ๅฝ’ๆ‰ฉๅฑ•ๆก†ๆžถๅ’Œๅ›บๅฎšVMๅ…ฑไบซๅบ“
-s             ็ฑปๅ’Œ็ฑปๅๆŽ’ๅบ
-S             ๆŒ‰ๅ็งฐๆŽ’ๅบ
-t             ้˜ปๆญขๅคดๆ–‡ไปถ่พ“ๅ‡บ๏ผŒไธป่ฆ็”จไบŽๆต‹่ฏ•
--list-arches  ๅˆ—ๅ‡บๆ–‡ไปถไธญ็š„ๆžถๆž„๏ผŒ็„ถๅŽ้€€ๅ‡บ
--sdk-ios      ๆŒ‡ๅฎš็š„iOS SDK็‰ˆๆœฌ๏ผˆไผš็œ‹ๅœจ/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS<version>.sdk
--sdk-mac      ๆŒ‡ๅฎšMac OS X็‰ˆๆœฌ๏ผˆไผš็œ‹ๅœจ/Developer/SDKs/MacOSX<version>.sdk
--sdk-root     ๆŒ‡ๅฎšๅฎŒๆ•ด็š„SDKๆ น่ทฏๅพ„๏ผˆๆˆ–ไฝฟ็”จ--sdk -IOS / - SDK -MAC็š„ๅฟซๆทๆ–นๅผ๏ผ‰
  • ๅฆ‚ๆžœdumpๅ‡บ็š„ๆ–‡ไปถๅชๆœ‰CDStructures.hๆ–‡ไปถ๏ผŒๅˆ™่กจ็คบๅ‡บ็Žฐ้”™่ฏฏใ€‚
  • ๅฆ‚ๆžœdumpๅฏผๅ‡บ็š„ๆ–‡ไปถๅ‘ฝๅไธบXXEncryptedXXX๏ผŒๅˆ™้œ€่ฆ้€š่ฟ‡AppCrackrใ€Clutchใ€dumpcrypted็ญ‰่ฟ›่กŒ็ ธๅฃณใ€‚ ่ฟ™้‡Œๆ˜ฏdumpcrypted็š„ไฝฟ็”จ

ไพ‹ๅญ

class-dump AppKit:

class-dump /System/Library/Frameworks/AppKit.framework

class-dump UIKit:

class-dump /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/UIKit.framework

class-dump UIKit and all the frameworks it uses:

class-dump /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/UIKit.framework -r --sdk-ios 4.3

class-dump UIKit (and all the frameworks it uses) from developer tools that have been installed in /Dev42 instead of /Developer:

class-dump /Dev42/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/UIKit.framework -r --sdk-root /Dev42/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk

ไฝฟ็”จdumpdecrypted็ป™App็ ธๅฃณๅŽ

class-dump --arch armv7 app.decrypted -H -o ./heads/

class-dump-z

ไธป้กต๏ผšhttps://code.google.com/p/networkpx/wiki/class_dump_z

ไฝฟ็”จwiki๏ผš https://code.google.com/archive/p/networkpx/wikis/class_dump_z.wiki

ๅฐ†class-dump-zๅฏๆ‰ง่กŒๆ–‡ไปถๆ”พๅˆฐ/usr/binไธ‹ๆˆ–่€…/usr/local/bin

ๅ‚่€ƒๆ–‡็Œฎ

Dumpdecrypted

่ทฏๅพ„

็”จiFileใ€Filza็ญ‰ๅทฅๅ…ทๆ‰พๅˆฐ๏ผš

iOS7ๅœจ/var/mobile/Application/

iOS8ๅœจ/var/mobile/Containers/Bundle/Application/

sandbox่ทฏๅพ„๏ผš/var/mobile/Containers/Data/Application/xxx

็ผ–่ฏ‘

ๆบ็ ๅœฐๅ€๏ผšhttps://github.com/stefanesser/dumpdecrypted/archive/master.zip

makeๅŽ็”Ÿๆˆdumpdecrypted.dylibๆ–‡ไปถ

ps: ่ฟ™้‡Œๆœ‰ๅ‡ ไธช็ผ–่ฏ‘ๅฅฝ็š„dylibๅฏไปฅไธ‹่ฝฝ๏ผš


https://github.com/iosre/Ready2Rock/blob/master/dumpdecrypted_5.dylib https://github.com/iosre/Ready2Rock/blob/master/dumpdecrypted_6.dylib https://github.com/iosre/Ready2Rock/blob/master/dumpdecrypted_7.dylib

็ ธๅฃณ

ๆŠŠ็ผ–่ฏ‘ๅฅฝ็š„dumpdecrypted.dylibๆ–‡ไปถๆ”พๅ…ฅๆƒณ่ฆ็ ธๅฃณ็š„app็š„documentsๆ–‡ไปถๅคน้‡Œ

ๆ‰ง่กŒไปฅไธ‹ไปฃ็ ็ ธๅฃณ๏ผš

DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/Application/AppPath/Name.app/Name 

่ฎฐๅฝ•ไธ€ๆฌกๆˆๅŠŸๆ—ฅๅฟ—

Last login: Sat Jul 16 21:36:39 on ttys000
localhost:~ lihao$ sudo ssh root@192.168.1.13
ssh: connect to host 192.168.1.13 port 22: Operation timed out
localhost:~ lihao$ sudo ssh root@192.168.1.13
root@192.168.1.13's password: 
iPhone:~ root# cd /var/mobile
iPhone:/var/mobile root# cd Containers/Data/Application/  
iPhone:/var/mobile/Containers/Data/Application/4ED085B4-FF7F-4B90-98F9-F17E241E1534 root# cd Documents/

iPhone:/var/mobile/Containers/Data/Application/4ED085B4-FF7F-4B90-98F9-F17E241E1534/Documents root# DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/Application/1BD15C2B-3661-4104-B8D4-3DE455EB4FB1/NewsBoard.app/NewsBoard

mach-o decryption dumper
DISCLAIMER: This tool is only meant for security research purposes, not for application crackers.

[+] detected 32bit ARM binary in memory.
[+] offset to cryptid found: @0xc6a90(from 0xc6000) = a90
[+] Found encrypted data at address 00004000 of length 12861440 bytes - type 1.
[+] Opening /private/var/mobile/Containers/Bundle/Application/1BD15C2B-3661-4104-B8D4-3DE455EB4FB1/NewsBoard.app/NewsBoard for reading.
[+] Reading header
[+] Detecting header type
[+] Executable is a FAT image - searching for right architecture
[+] Correct arch is at offset 16384 in the file
[+] Opening NewsBoard.decrypted for writing.
[+] Copying the not encrypted start of the file
[+] Dumping the decrypted data into the file
[+] Copying the not encrypted remainder of the file
[+] Setting the LC_ENCRYPTION_INFO->cryptid to 0 at offset 4a90
[+] Closing original file
[+] Closing dump file
iPhone:/var/mobile/Containers/Data/Application/4ED085B4-FF7F-4B90-98F9-F17E241E1534/Documents 

root# 

ๆˆๅŠŸๅŽไผš็”ŸๆˆName.decryptedๆ–‡ไปถ

ๅˆ†ๆž

ๅฝ“็ ธๅฃณๅฎŒๆฏ•ๅŽ๏ผŒๅฐ†็ ธๅฃณ็”Ÿๆˆ็š„ ***.decrypted ๆ–‡ไปถๆ‹ท่ด่‡ณไฝ ็š„MACใ€‚

้€š่ฟ‡class-dumpๅˆ†ๆž๏ผš

class-dump --arch armv7 /Users/lihao/Desktop/Name.decrypted -H -o path/

ๆณจๆ„

  • ้€š่ฟ‡Cydia็ญ‰็ฌฌไธ‰ๆ–นๆธ ้“ไธ‹่ฝฝ็š„appๆœ‰็š„ไธ้œ€่ฆ็ ธๅฃณ๏ผŒๅฝ“ไฝฟ็”จdumpdecryptedๆ—ถไผšๆ็คบไปฅไธ‹ไฟกๆฏ๏ผš This mach-o file is not encrypted. Nothing was decrypted.
  • ๅฝ“็ ธๅฃณๅฎŒๆฏ•ๅŽ๏ผŒไฝฟ็”จ class-dump ไป็„ถๅชๅฏผๅ‡บ CDStructures.h ไธ€ไธชๆ–‡ไปถ๏ผŒๅˆ™ๅฏ่ƒฝๆžถๆž„้€‰ๆ‹ฉ้”™่ฏฏ๏ผ›ๅ› ไธบdumpdecryptedๅช่ƒฝ็ ธ็›ธๅบ”ๆ‰‹ๆœบๅค„็†ๅ™จๅฏนๅบ”็š„ๅฃณใ€‚

ๅ‚่€ƒๆ–‡็Œฎ

Reveal

Revealไธป้กต๏ผšhttp://revealapp.com

Reveal ๆ˜ฏไธ€ไธช็•Œ้ข่ฐƒ่ฏ•ๅทฅๅ…ท๏ผŒ่ฟ™้‡Œๆœ‰ไธ€็ฏ‡iOSๅผ€ๅ‘ไธญ้›†ๆˆReveal็š„ๆ•™็จ‹๏ผŒๆ‰€ไปฅๆˆ‘ไปฌๅฐฑไธ่ฎจ่ฎบๅฆ‚ไฝ•้›†ๆˆๅˆฐ่‡ชๅทฑ็š„ๅทฅ็จ‹ไธญ๏ผŒๆŽฅไธ‹ๆฅๆˆ‘ไปฌ็œ‹ไธ€ไธ‹ๅฆ‚ไฝ•ไฝฟ็”จRevealๆŸฅ็œ‹ไปปๆ„appใ€‚

้œ€่ฆ็š„ไธœ่ฅฟ๏ผš

  • ่ถŠ็‹ฑ่ฎพๅค‡
  • Cydia
  • iFile
  • SSH

ไฝฟ็”จCydiaไธ‹่ฝฝ Reveal Loader ๅนถๅฎ‰่ฃ…ๅŽre-springๆˆ–้‡ๅฏiOS่ฎพๅค‡ใ€‚ๅœจ็ณป็ปŸ่ฎพ็ฝฎไธญๆ‰พๅˆฐ Reveal -> Enabled Applications ่ฟ›่กŒ้…็ฝฎ๏ผŒๆ‰“ๅผ€ไฝ ๆƒณ่ฆReveal็š„appใ€‚

ๅปบ่ฎฎ้œ€่ฆๆŸฅ็œ‹ๅ“ชไธชๅผ€ๅ“ชไธช๏ผŒๅ…ถไป–็š„ๅ…ณ้—ญๆŽ‰๏ผŒ่ฟ™ๆ ทRevealๅŠ ่ฝฝ้€Ÿๅบฆไผšๅฟซไธ€็‚นใ€‚

่ฟ™ๆ˜ฏๅ‚่€ƒๆ–‡็Œฎไธญ็š„ๅ›พ

็ฌฆๅท่กจๅŽ†ๆฅๆ˜ฏ้€†ๅ‘ๅทฅ็จ‹ไธญ็š„โ€œๅฟ…ไบ‰ไน‹ๅœฐโ€๏ผŒ่€ŒiOSๅบ”็”จๅœจไธŠ็บฟๅ‰้ƒฝไผš่ฃๅŽป็ฌฆๅท่กจ๏ผŒไปฅ้ฟๅ…่ขซ้€†ๅ‘ๅˆ†ๆžใ€‚

็›ดๆŽฅ็œ‹ๆ•ˆๆžœ,ๆ”ฏไป˜ๅฎๆขๅค็ฌฆๅท่กจๅŽ็š„ๆ ทๅญ:

ๆ”ฏไป˜ๅฎๆขๅค็ฌฆๅท่กจๅŽ

ๆ–‡็ซ ๆœ‰็‚น้•ฟ๏ผŒ่ฏท่€ๅฟƒ็œ‹ๅˆฐๆœ€ๅŽ๏ผŒไบฎ็‚นๅœจๆœ€ๅŽใ€‚

ไธบไป€ไนˆ่ฆๆขๅค็ฌฆๅท่กจ ้€†ๅ‘ๅทฅ็จ‹ไธญ๏ผŒ่ฐƒ่ฏ•ๅ™จ็š„ๅŠจๆ€ๅˆ†ๆžๆ˜ฏๅฟ…ไธๅฏๅฐ‘็š„๏ผŒ่€Œ Xcode + lldb ็กฎๅฎžๆ˜ฏ้žๅธธๅฅฝ็š„่ฐƒ่ฏ•ๅˆฉๅ™จ, ๆฏ”ๅฆ‚ๆˆ‘ไปฌๅœจXcode้‡Œๅฏไปฅๅพˆๆ–นไพฟ็š„ๆŸฅ็œ‹่ฐƒ็”จๅ †ๆ ˆ๏ผŒๅฆ‚ไธŠ้ข้‚ฃๅผ ๅ›พๅฏไปฅๅพˆๆธ…ๆ™ฐ็š„็œ‹ๅˆฐๆ”ฏไป˜ๅฎ็™ปๅฝ•็š„RPC่ฐƒ็”จ่ฟ‡็จ‹ใ€‚

ๅฎž้™…ไธŠ๏ผŒๅฆ‚ๆžœๆˆ‘ไปฌไธๆขๅค็ฌฆๅท่กจ็š„่ฏ๏ผŒไฝ ็œ‹ๅˆฐ็š„่ฐƒ่ฏ•้กต้ขๅบ”่ฏฅๆ˜ฏไธ‹้ข่ฟ™ไธชๆ ทๅญ๏ผš

ๆขๅค็ฌฆๅท่กจๅ‰

ๅŒไธ€ไธชๅ‡ฝๆ•ฐ่ฐƒ็”จ่ฟ‡็จ‹๏ผŒXcode็š„ๆ˜พ็คบ็ฎ€็›ดๅคฉๅทฎๅœฐๅˆซใ€‚

ๅŽŸๅ› ๆ˜ฏ๏ผŒXcodeๆ˜พ็คบ่ฐƒ็”จๅ †ๆ ˆไธญ็ฌฆๅทๆ—ถ๏ผŒๅชไผšๆ˜พ็คบ็ฌฆๅท่กจไธญๆœ‰็š„็ฌฆๅทใ€‚ไธบไบ†ๆˆ‘ไปฌ่ฐƒ่ฏ•่ฟ‡็จ‹็š„้กบๅˆฉ๏ผŒๆˆ‘ไปฌๆœ‰ๅฟ…่ฆๆŠŠๅฏๆ‰ง่กŒๆ–‡ไปถไธญ็š„็ฌฆๅท่กจๆขๅคๅ›žๆฅใ€‚

็ฌฆๅท่กจๆ˜ฏไป€ไนˆ ๆˆ‘ไปฌ่ฆๆขๅค็ฌฆๅท่กจ๏ผŒ้ฆ–ๅ…ˆ่ฆ็Ÿฅ้“็ฌฆๅท่กจๆ˜ฏไป€ไนˆ๏ผŒไป–ๆ˜ฏๆ€Žไนˆๅญ˜ๅœจไบŽ Mach-O ๆ–‡ไปถไธญ็š„ใ€‚

็ฌฆๅท่กจๅ‚จๅญ˜ๅœจ Mach-O ๆ–‡ไปถ็š„ __LINKEDIT ๆฎตไธญ๏ผŒๆถ‰ๅŠๅ…ถไธญ็š„็ฌฆๅท่กจ๏ผˆSymbol Table๏ผ‰ๅ’Œๅญ—็ฌฆไธฒ่กจ๏ผˆString Table๏ผ‰ใ€‚

่ฟ™้‡Œๆˆ‘ไปฌ็”จ MachOView ๆ‰“ๅผ€ๆ”ฏไป˜ๅฎ็š„ๅฏๆ‰ง่กŒๆ–‡ไปถ๏ผŒๆ‰พๅˆฐๅ…ถไธญ็š„ Symbol Table ้กนใ€‚

็ฌฆๅท่กจ็š„็ป“ๆž„ๆ˜ฏไธ€ไธช่ฟž็ปญ็š„ๅˆ—่กจ๏ผŒๅ…ถไธญ็š„ๆฏไธ€้กน้ƒฝๆ˜ฏไธ€ไธช struct nlistใ€‚

// ไฝไบŽ็ณป็ปŸๅบ“ <macho-o/nlist.h> ๅคดๆ–‡ไปถไธญ struct nlist { union { //็ฌฆๅทๅๅœจๅญ—็ฌฆไธฒ่กจไธญ็š„ๅ็งป้‡ uint32_t n_strx;
} n_un; uint8_t n_type; uint8_t n_sect; int16_t n_desc; //็ฌฆๅทๅœจๅ†…ๅญ˜ไธญ็š„ๅœฐๅ€๏ผŒ็ฑปไผผไบŽๅ‡ฝๆ•ฐๆŒ‡้’ˆ uint32_t n_value; }; ่ฟ™้‡Œ้‡็‚นๅ…ณๆณจ็ฌฌไธ€้กนๅ’Œๆœ€ๅŽไธ€้กน๏ผŒ็ฌฌไธ€้กนๆ˜ฏ็ฌฆๅทๅๅœจๅญ—็ฌฆไธฒ่กจไธญ็š„ๅ็งป้‡๏ผŒ็”จไบŽ่กจ็คบๅ‡ฝๆ•ฐๅ๏ผŒๆœ€ๅŽไธ€้กนๆ˜ฏ็ฌฆๅทๅœจๅ†…ๅญ˜ไธญ็š„ๅœฐๅ€๏ผŒ็ฑปไผผไบŽๅ‡ฝๆ•ฐๆŒ‡้’ˆ๏ผˆ่ฟ™้‡Œๅช่ฏดๆ˜Žๅคงๆฆ‚็š„็ป“ๆž„๏ผŒ่ฏฆ็ป†็š„ไฟกๆฏ่ฏทๅ‚่€ƒๅฎ˜ๆ–นMach Oๆ–‡ไปถๆ ผๅผ็š„ๆ–‡ๆกฃ๏ผ‰ใ€‚

ไนŸๅฐฑๆ˜ฏ่ฏดๅฆ‚ๆžœๆˆ‘ไปฌ็Ÿฅ้“ไบ†็ฌฆๅทๅๅ’Œๅ†…ๅญ˜ๅœฐๅ€็š„ๅฏนๅบ”ๅ…ณ็ณป๏ผŒๆˆ‘ไปฌๆ˜ฏๅฏไปฅๆ นๆฎ่ฟ™ไธช็ป“ๆž„ๆฅ้€†ๅ‘ๆž„้€ ๅ‡บ็ฌฆๅท่กจๆ•ฐๆฎ็š„ใ€‚

็Ÿฅ้“ไบ†ๅฆ‚ไฝ•ๆž„้€ ็ฌฆๅท่กจ๏ผŒไธ‹ไธ€ๆญฅๅฐฑๆ˜ฏๆ”ถ้›†็ฌฆๅทๅๅ’Œๅ†…ๅญ˜ๅœฐๅ€็š„ๅฏนๅบ”ๅ…ณ็ณปไบ†ใ€‚

่Žทๅ–OCๆ–นๆณ•็š„็ฌฆๅท่กจ ๅ› ไธบOC่ฏญ่จ€็š„็‰นๆ€ง๏ผŒ็ผ–่ฏ‘ๅ™จไผšๅฐ†็ฑปๅใ€ๅ‡ฝๆ•ฐๅ็ญ‰็ผ–่ฏ‘่ฟ›ๆœ€ๅŽ็š„ๅฏๆ‰ง่กŒๆ–‡ไปถไธญ๏ผŒๆ‰€ไปฅๆˆ‘ไปฌๅฏไปฅๆ นๆฎMach-Oๆ–‡ไปถ็š„็ป“ๆž„้€†ๅ‘่ฟ˜ๅŽŸๅ‡บๅทฅ็จ‹้‡Œ็š„ๆ‰€ๆœ‰็ฑป๏ผŒ่ฟ™ไนŸๅฐฑๆ˜ฏๅคงๅ้ผŽ้ผŽ็š„้€†ๅ‘ๅทฅๅ…ท class-dump ไบ†ใ€‚class-dump ๅ‡บๆฅ็š„ๅคดๆ–‡ไปถ้‡Œๆ˜ฏๆœ‰ๅ‡ฝๆ•ฐๅœฐๅ€็š„๏ผš

ๆ‰€ไปฅๆˆ‘ไปฌๅช่ฆๅฏนclass-dump็š„ๆบ็ ็จไฝœไฟฎๆ”น๏ผŒๅณๅฏ่Žทๅ–ๆˆ‘ไปฌ่ฆ็š„ไฟกๆฏใ€‚

็ฌฆๅท่กจๆขๅคๅทฅๅ…ท ๆ•ด็†ๅฎŒๆ•ฐๆฎๆ ผๅผ๏ผŒๅˆ็†ๆธ…ไบ†ๆ•ฐๆฎๆฅๆบ๏ผŒๆˆ‘ไปฌๅฐฑๅฏไปฅๅ†™ๅทฅๅ…ทไบ†ใ€‚

ๅฎž็Žฐ่ฟ‡็จ‹ๅฐฑไธ่ฏฆ็ป†่ฏดๆ˜Žไบ†๏ผŒๅทฅๅ…ทๅผ€ๆบๅœจๆˆ‘็š„GithubไธŠไบ†๏ผŒ้“พๆŽฅ๏ผš https://github.com/tobefuturer/restore-symbol

ๆˆ‘ไปฌๆฅ็œ‹็œ‹ๆ€Žไนˆ็”จ่ฟ™ไธชๅทฅๅ…ท๏ผš

1.ไธ‹่ฝฝๆบ็ ็ผ–่ฏ‘

git clone --recursive https://github.com/tobefuturer/restore-symbol.git cd restore-symbol && make ./restore-symbol 2.ๆขๅคOC็š„็ฌฆๅท่กจ๏ผŒ้žๅธธ็ฎ€ๅ•

1 ./restore-symbol ./origin_AlipayWallet -o ./AlipayWallet_with_symbol origin_AlipayWallet ไธบClutch็ ธๅฃณๅŽ๏ผŒๆฒกๆœ‰็ฌฆๅท่กจ็š„ Mach-O ๆ–‡ไปถ -o ๅŽ้ข่ทŸ่พ“ๅ‡บๆ–‡ไปถไฝ็ฝฎ

3.ๆŠŠ Mach-O ๆ–‡ไปถ้‡็ญพๅๆ‰“ๅŒ…๏ผŒ็œ‹ๆ•ˆๆžœ

ๆ–‡ไปถๆขๅค็ฌฆๅท่กจๅŽ๏ผŒๅคšๅ‡บไบ†20M็š„็ฌฆๅท่กจไฟกๆฏ

Xcode้‡ŒๆŸฅ็œ‹่ฐƒ็”จๆ ˆ

ๅฏไปฅ็œ‹ๅˆฐ๏ผŒOCๅ‡ฝๆ•ฐ่ฟ™้ƒจๅˆ†็š„็ฌฆๅทๅทฒ็ปๆขๅคไบ†๏ผŒๅ‡ฝๆ•ฐ่ฐƒ็”จๆ ˆ้‡Œๅทฒ็ป่ƒฝ็œ‹ๅ‡บๅคง่‡ด็š„่ฐƒ็”จ่ฟ‡็จ‹ไบ†๏ผŒไฝ†ๆ˜ฏๆ”ฏไป˜ๅฎ้‡Œ๏ผŒ้‡‡็”จไบ†block็š„ๅ›ž่ฐƒๅฝขๅผ๏ผŒๆ‰€ไปฅ่ฟ˜ๆœ‰ๅพˆๅคงไธ€้ƒจๅˆ†็š„็ฌฆๅทๆฒก่ƒฝๆญฃ็กฎๆ˜พ็คบใ€‚

ไธ‹้ขๆˆ‘ไปฌๅฐฑๆฅ็œ‹็œ‹ๆ€Žไนˆๆ ทๆขๅค่ฟ™้ƒจๅˆ†block็š„็ฌฆๅทใ€‚

่Žทๅ–block็š„็ฌฆๅทไฟกๆฏ ่ฟ˜ๆ˜ฏๅŒๆ ท็š„ๆ€่ทฏ๏ผŒ่ฆๆขๅคblock็š„็ฌฆๅทไฟกๆฏ๏ผŒๆˆ‘ไปฌๅฟ…้กป็Ÿฅ้“blockๅœจๆ–‡ไปถไธญ็š„ๅ‚จๅญ˜ๅฝขๅผใ€‚

blockๅœจๅ†…ๅญ˜ไธญ็š„็ป“ๆž„ ้ฆ–ๅ…ˆ๏ผŒๆˆ‘ไปฌๅ…ˆๅˆ†ๆžไธ‹่ฟ่กŒๆ—ถ๏ผŒblockๅœจๅ†…ๅญ˜ไธญ็š„ๅญ˜ๅœจๅฝขๅผใ€‚blockๅœจๅ†…ๅญ˜ไธญๆ˜ฏไปฅไธ€ไธช็ป“ๆž„ไฝ“็š„ๅฝขๅผๅญ˜ๅœจ็š„๏ผŒๅคง่‡ด็š„็ป“ๆž„ๅฆ‚ไธ‹๏ผš

struct __block_impl { /** blockๅœจๅ†…ๅญ˜ไธญไนŸๆ˜ฏ็ฑปNSObject็š„็ป“ๆž„ไฝ“๏ผŒ ็ป“ๆž„ไฝ“ๅผ€ๅง‹ไฝ็ฝฎๆ˜ฏไธ€ไธชisaๆŒ‡้’ˆ */ Class isa;

/** ่ฟ™ไธคไธชๅ˜้‡ๆš‚ๆ—ถไธๅ…ณๅฟƒ */ int flags; int reserved;

/** ็œŸๆญฃ็š„ๅ‡ฝๆ•ฐๆŒ‡้’ˆ๏ผ๏ผ */ void (*invoke)(...); ... } ่ฏดๆ˜Žไธ‹blockไธญ็š„isaๆŒ‡้’ˆ๏ผŒๆ นๆฎๅฎž้™…ๆƒ…ๅ†ตไผšๆœ‰ไธ‰็งไธๅŒ็š„ๅ–ๅ€ผ๏ผŒๆฅ่กจ็คบไธๅŒ็ฑปๅž‹็š„block๏ผš

_NSConcreteStackBlock

ๆ ˆไธŠ็š„block๏ผŒไธ€่ˆฌblockๅˆ›ๅปบๆ—ถๆ˜ฏๅœจๆ ˆไธŠๅˆ†้…ไบ†ไธ€ไธชblock็ป“ๆž„ไฝ“็š„็ฉบ้—ด๏ผŒ็„ถๅŽๅฏนๅ…ถไธญ็š„isa็ญ‰ๅ˜้‡่ต‹ๅ€ผใ€‚

_NSConcreteMallocBlock

ๅ †ไธŠ็š„block๏ผŒๅฝ“block่ขซๅŠ ๅ…ฅๅˆฐGCDๆˆ–่€…่ขซๅฏน่ฑกๆŒๆœ‰ๆ—ถ๏ผŒๅฐ†ๆ ˆไธŠ็š„blockๅคๅˆถๅˆฐๅ †ไธŠ๏ผŒๆญคๆ—ถๅคๅˆถๅพ—ๅˆฐ็š„block็ฑปๅž‹ๅ˜ไธบไบ†_NSConcreteMallocBlockใ€‚

_NSConcreteGlobalBlock

ๅ…จๅฑ€้™ๆ€็š„block๏ผŒๅฝ“blockไธไพ่ต–ไบŽไธŠไธ‹ๆ–‡็Žฏๅขƒ๏ผŒๆฏ”ๅฆ‚ไธๆŒๆœ‰blockๅค–็š„ๅ˜้‡ใ€ๅชไฝฟ็”จblockๅ†…้ƒจ็š„ๅ˜้‡็š„ๆ—ถๅ€™๏ผŒblock็š„ๅ†…ๅญ˜ๅˆ†้…ๅฏไปฅๅœจ็ผ–่ฏ‘ๆœŸๅฐฑๅฎŒๆˆ๏ผŒๅˆ†้…ๅœจๅ…จๅฑ€็š„้™ๆ€ๅธธ้‡ๅŒบใ€‚

็ฌฌ2็งblockๅœจ่ฟ่กŒๆ—ถๆ‰ไผšๅ‡บ็Žฐ๏ผŒๆˆ‘ไปฌๅชๅ…ณๆณจ1ใ€3ไธค็ง๏ผŒไธ‹้ขๅฐฑๅˆ†ๆž่ฟ™ไธค็งisaๆŒ‡้’ˆๅ’Œblock็ฌฆๅทๅœฐๅ€ไน‹้—ด็š„ๅ…ณ่”ใ€‚

block isaๆŒ‡้’ˆๅ’Œ็ฌฆๅทๅœฐๅ€ไน‹้—ด็š„ๅ…ณ่” ๅˆ†ๆž่ฟ™้ƒจๅˆ†้œ€่ฆ็”จๅˆฐIDA่ฟ™ไธชๅๆฑ‡็ผ–่ฝฏไปถ, ่ฟ™้‡Œ็ป“ๅˆไธคไธชๅฎž้™…็š„ๅฐไพ‹ๅญๆฅ่ฏดๆ˜Ž๏ผš

1._NSConcreteStackBlock ๅ‡่ฎพๆˆ‘ไปฌ็š„ๆบไปฃ็ ๆ˜ฏ่ฟ™ๆ ทๅพˆ็ฎ€ๅ•็š„ไธ€ไธชblock๏ผš

11 @implementation ViewController

  • (void)viewDidLoad { int t = 2; void (^ foo)() = ^(){ NSLog(@"%d", t); //block ๅผ•็”จไบ†ๅค–้ƒจ็š„ๅ˜้‡t }; foo(); } @end ็ผ–่ฏ‘ๅฎŒๅŽ๏ผŒๅฎž้™…็š„ๆฑ‡็ผ–้•ฟ่ฟ™ไธชๆ ทๅญ๏ผš

ๅฎž้™…่ฟ่กŒๆ—ถ๏ผŒblock็š„ๆž„้€ ่ฟ‡็จ‹ๆ˜ฏ่ฟ™ๆ ท๏ผš

ไธบblockๅผ€่พŸๆ ˆ็ฉบ้—ด ไธบblock็š„isaๆŒ‡้’ˆ่ต‹ๅ€ผ๏ผˆไธ€ๅฎšไผšๅผ•็”จๅ…จๅฑ€ๅ˜้‡๏ผš_NSConcreteStackBlock๏ผ‰ ่Žทๅ–ๅ‡ฝๆ•ฐๅœฐๅ€๏ผŒ่ต‹ๅ€ผ็ป™ๅ‡ฝๆ•ฐๆŒ‡้’ˆ ๆ‰€ไปฅๆˆ‘ไปฌๅฏไปฅๆ•ด็†ๅ‡บ่ฟ™ๆ ทไธ€ไธช็‰นๅพ๏ผš

้‡็‚นๆฅไบ†!!!

ๅ‡กๆ˜ฏไปฃ็ ้‡Œ็”จๅˆฐไบ†ๆ ˆไธŠ็š„block๏ผŒไธ€ๅฎšไผš่Žทๅ–__NSConcreteStackBlockไฝœไธบisaๆŒ‡้’ˆ๏ผŒๅŒๆ—ถไผš็ดงๆŽฅ็€่Žทๅ–ไธ€ไธชๅ‡ฝๆ•ฐๅœฐๅ€๏ผŒ้‚ฃไธชๅ‡ฝๆ•ฐๅœฐๅ€ๅฐฑๆ˜ฏblock็š„ๅ‡ฝๆ•ฐๅœฐๅ€ใ€‚

็ป“ๅˆไธ‹้ข่ฟ™ไธชๅ›พ๏ผŒไป”็ป†็†่งฃไธŠ้ข่ฟ™ๅฅ่ฏ ๏ผˆ่ฟ™ๅผ ๅ›พๅ’ŒไธŠ้ข้‚ฃๅผ ๅ›พๆ˜ฏๅŒไธ€ไธชๆ–‡ไปถ๏ผŒไธ่ฟ‡่ฃๆŽ‰ไบ†็ฌฆๅท่กจ๏ผ‰

ๅˆฉ็”จ่ฟ™ไธช็‰นๅพ๏ผŒ้€†ๅ‘ๅˆ†ๆžๆ—ถๆˆ‘ไปฌๅฏไปฅๅšๅฆ‚ไธ‹ๆŽจๆ–ญ๏ผš

ๅœจไธ€ไธชOCๆ–นๆณ•้‡Œๅ‘็Žฐๅผ•็”จไบ†__NSConcreteStackBlock่ฟ™ไธชๅ˜้‡๏ผŒ้‚ฃไนˆๅœจ่ฟ™้™„่ฟ‘๏ผŒไธ€ๅฎšไผšๅ‡บ็Žฐไธ€ไธชๅ‡ฝๆ•ฐๅœฐๅ€๏ผŒ่ฟ™ไธชๅ‡ฝๆ•ฐๅœฐๅ€ๅฐฑๆ˜ฏ่ฟ™ไธชOCๆ–นๆณ•้‡Œ็š„ไธ€ไธชblockใ€‚

ๆฏ”ๅฆ‚ไธŠ้ขๅ›พไธญ๏ผŒๆˆ‘ไปฌๅ‘็Žฐ viewDidLoad ้‡Œ๏ผŒๅผ•็”จไบ†__NSConcreteStackBlock,ๅŒๆ—ถ็ดงๆŽฅ็€ๅŠ ่ฝฝไบ† sub_100049D4 ็š„ๅ‡ฝๆ•ฐๅœฐๅ€๏ผŒ้‚ฃๆˆ‘ไปฌๅฐฑๅฏไปฅ่ฎคๅฎšsub_100049D4ๆ˜ฏviewDidLoad้‡Œ็š„ไธ€ไธชblock, sub_100049D4ๅ‡ฝๆ•ฐ็š„็ฌฆๅทๅๅบ”่ฏฅๆ˜ฏ viewDidLoad_block.

  1. _NSConcreteGlobalBlock ๅ…จๅฑ€็š„้™ๆ€block๏ผŒๆ˜ฏ้‚ฃ็งไธๅผ•็”จblockๅค–ๅ˜้‡็š„block๏ผŒไป–ๅ› ไธบไธๅผ•็”จๅค–้ƒจๅ˜้‡๏ผŒๆ‰€ไปฅไป–ๅฏไปฅๅœจ็ผ–่ฏ‘ๆœŸๅฐฑ่ฟ›่กŒๅ†…ๅญ˜ๅˆ†้…ๆ“ไฝœ๏ผŒไนŸไธ็”จๆ‹…ๅฟƒblock็š„ๅคๅˆถ็ญ‰็ญ‰ๆ“ไฝœ๏ผŒไป–ๅญ˜ๅœจไบŽๅฏๆ‰ง่กŒๆ–‡ไปถ็š„ๅธธ้‡ๅŒบ้‡Œใ€‚

ไธๅคช็†่งฃ็š„่ฏ๏ผŒ็œ‹ไธชไพ‹ๅญ๏ผš

ๆˆ‘ไปฌๆŠŠๆบไปฃ็ ๆ”นๆˆ่ฟ™ๆ ท๏ผš

@implementation ViewController

  • (void)viewDidLoad {

void (^ foo)() = ^(){ //block ไธๅผ•็”จๅค–้ƒจ็š„ๅ˜้‡ NSLog(@"%d", 123); }; foo(); } @end ้‚ฃไนˆๅœจ็ผ–่ฏ‘ๅŽไผšๅ˜ๆˆ่ฟ™ๆ ท๏ผš

้‚ฃไนˆๅ€Ÿ้‰ดไธŠ้ข็š„ๆ€่ทฏ๏ผŒๅœจ้€†ๅ‘ๅˆ†ๆž็š„ๆ—ถๅ€™๏ผŒๆˆ‘ไปฌๅฏไปฅ่ฟ™ไนˆๆŽจๆ–ญ

ๅœจ้™ๆ€ๅธธ้‡ๅŒบๅ‘็Žฐไธ€ไธช_NSConcreteGlobalBlock็š„ๅผ•็”จ ่ฟ™ไธชๅœฐๆ–นๅฟ…็„ถๅญ˜ๅœจไธ€ไธชblock็š„็ป“ๆž„ไฝ“ๆ•ฐๆฎ ๅœจ่ฟ™ไธช็ป“ๆž„ไฝ“็ฌฌ16ไธชๅญ—่Š‚็š„ๅœฐๆ–นไผšๅ‡บ็Žฐไธ€ไธชๅ€ผ๏ผŒ่ฟ™ไธชๅ€ผๆ˜ฏไธ€ไธชblock็š„ๅ‡ฝๆ•ฐๅœฐๅ€ 3. block ็š„ๅตŒๅฅ—็ป“ๆž„ ๅฎž้™…ๅœจไฝฟ็”จไธญ๏ผŒๅฏ่ƒฝไผšๅ‡บ็Žฐblockๅ†…ๅตŒblock็š„ๆƒ…ๅ†ต๏ผš

  • (void)viewDidLoad { dispatch_async(background_queue ,^{ ... dispatch_async(main_queue, ^{ ...
    }); }); } ๆ‰€ไปฅ่ฟ™้‡Œblockๅฐฑๅ‡บ็Žฐไบ†็ˆถๅญๅ…ณ็ณป๏ผŒๅฆ‚ๆžœๆˆ‘ไปฌๅฐ†่ฟ™ไบ›็ˆถๅญๅ…ณ็ณปๆ”ถ้›†่ตทๆฅ๏ผŒๅฐฑๅฏไปฅๅ‘็Žฐ๏ผŒ่ฟ™ไบ›ๅ…ณ็ณปไผšๆž„ๆˆๅ›พ่ฎบ้‡Œ็š„ๆฃฎๆž—็ป“ๆž„๏ผŒ่ฟ™้‡Œๅฏไปฅ็ฎ€ๅ•็”จ้€’ๅฝ’็š„ๆทฑๅบฆไผ˜ๅ…ˆๆœ็ดขๆฅๅค„็†๏ผŒ่ฏฆ็ป†่ฟ‡็จ‹ไธๅ†ๆ่ฟฐใ€‚

block็ฌฆๅท่กจๆๅ–่„šๆœฌ๏ผˆIDA+python๏ผ‰ ๆ•ด็†ไธŠ้ข็š„ๆ€่ทฏ๏ผŒๆˆ‘ไปฌๅ‘็Žฐๆœ็ดข่ฟ‡็จ‹ไพ่ต–ไบŽIDAๆไพ›ๅ„็งๅผ•็”จไฟกๆฏ๏ผŒ่€ŒIDAๆ˜ฏๆไพ›ไบ†็ผ–็จ‹ๆŽฅๅฃ็š„๏ผŒๅฏไปฅๅˆฉ็”จ่ฟ™ไบ›ๆŽฅๅฃๆฅๆๅ–ๅผ•็”จไฟกๆฏใ€‚

IDAๆไพ›็š„ๆ˜ฏPython็š„SDK๏ผŒๆœ€ๅŽๅฎŒๆˆ็š„่„šๆœฌไนŸๆ”พๅœจไป“ๅบ“้‡Œsearch_oc_block/ida_search_block.pyใ€‚

ๆๅ–block็ฌฆๅท่กจ ่ฟ™้‡Œ็ฎ€ๅ•ไป‹็ปไธ‹ๆ€Žไนˆไฝฟ็”จไธŠ้ข่ฟ™ไธช่„šๆœฌ

็”จIDAๆ‰“ๅผ€ๆ”ฏไป˜ๅฎ็š„ Mach-O ๆ–‡ไปถ ็ญ‰ๅพ…ๅˆ†ๆžๅฎŒๆˆ๏ผ ๅฏ่ƒฝ่ฆไธ€ไธชๅฐๆ—ถ Alt + F7 ๆˆ–่€… ่œๅ•ๆ  File -> Script file...

็ญ‰ๅพ…่„šๆœฌ่ฟ่กŒๅฎŒๆˆ๏ผŒ้ข„่ฎก30s่‡ณ60s๏ผŒ่ฟ่กŒ่ฟ‡็จ‹ไธญไผšๆœ‰่ฟ™ๆ ท็š„ๅผน็ช—

ๅผน็ช—ๆถˆๅคฑๅณblock็ฌฆๅท่กจๆๅ–ๅฎŒๆˆ ๅœจIDAๆ‰“ๅผ€ๆ–‡ไปถ็š„็›ฎๅฝ•ไธ‹,ไผš่พ“ๅ‡บไธ€ไปฝๅไธบblock_symbol.json็š„jsonๆ ผๅผblock็ฌฆๅท่กจ

ๆขๅค็ฌฆๅท่กจ&ๅฎž้™…ๅˆ†ๆž ็”จไน‹ๅ‰็š„็ฌฆๅท่กจๆขๅคๅทฅๅ…ท๏ผŒๅฐ†block็š„็ฌฆๅท่กจๅฏผๅ…ฅMach-Oๆ–‡ไปถ

1 ./restore-symbol ./origin_AlipayWallet -o ./AlipayWallet_with_symbol -j block_symbol.json -j ๅŽ้ข่ทŸไธŠไน‹ๅ‰ๅพ—ๅˆฐ็š„json็ฌฆๅท่กจ

ๆœ€ๅŽๅพ—ๅˆฐไธ€ไปฝๅŒๆ—ถๅ…ทๆœ‰OCๅ‡ฝๆ•ฐ็ฌฆๅท่กจๅ’Œblock็ฌฆๅท่กจ็š„ๅฏๆ‰ง่กŒๆ–‡ไปถ

่ฟ™้‡Œ็ฎ€ๅ•ไป‹็ปไธ€ไธชๅˆ†ๆžๆกˆไพ‹, ไฝ ๅฐฑ่ƒฝไฝ“ไผšๅˆฐ่ฟ™ไธชๅทฅๅ…ท็š„ๅผบๅคงไน‹ๅค„ไบ†ใ€‚

ๅœจXcode้‡Œๅฏน -[UIAlertView show] ่ฎพ็ฝฎๆ–ญ็‚น

่ฟ่กŒ็จ‹ๅบ๏ผŒๅนถๅœจๆ”ฏไป˜ๅฎ็š„็™ปๅฝ•้กต้ข่พ“ๅ…ฅๆ‰‹ๆœบๅทๅ’Œ้”™่ฏฏ็š„ๅฏ†็ ๏ผŒ็‚นๅ‡ป็™ปๅฝ• Xcodeไผšๅœจโ€˜ๅฏ†็ ้”™่ฏฏโ€™็š„่ญฆๅ‘Šๆก†ๅผนๅ‡บๆ—ถๅœไธ‹๏ผŒๅทฆไพงไผšๆ˜พ็คบๅ‡บ่ฟ™ๆ ท็š„่ฐƒ็”จๆ ˆ ไธ€ๅผ ๅ›พ็œ‹ๅฎŒๆ”ฏไป˜ๅฎ็š„็™ปๅฝ•่ฟ‡็จ‹

ๅ‚่€ƒๆ–‡็Œฎ

//                            _ooOoo_
//                           o8888888o
//                           88" . "88
//                           (| -_- |)
//                            O\ = /O
//                        ____/`---'\____
//                      .   ' \\| |// `.
//                       / \\||| : |||// \
//                     / _||||| -:- |||||- \
//                       | | \\\ - /// | |
//                     | \_| ''\---/'' | |
//                      \ .-\__ `-` ___/-. /
//                   ___`. .' /--.--\ `. . __
//                ."" '< `.___\_<|>_/___.' >'"".
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |
//                 \ \ `-. \_ __\ /__ _/ .-` / /
//         ======`-.____`-.___\_____/___.-`____.-'======
//                            `=---='
//
//         .............................................
//                  ไฝ›็ฅ–้•‡ๆฅผ                  BUG่พŸๆ˜“
//          ไฝ›ๆ›ฐ:
//                  ๅ†™ๅญ—ๆฅผ้‡Œๅ†™ๅญ—้—ด๏ผŒๅ†™ๅญ—้—ด้‡Œ็จ‹ๅบๅ‘˜๏ผ›
//                  ็จ‹ๅบไบบๅ‘˜ๅ†™็จ‹ๅบ๏ผŒๅˆๆ‹ฟ็จ‹ๅบๆข้…’้’ฑใ€‚
//                  ้…’้†’ๅชๅœจ็ฝ‘ไธŠๅ๏ผŒ้…’้†‰่ฟ˜ๆฅ็ฝ‘ไธ‹็œ ๏ผ›
//                  ้…’้†‰้…’้†’ๆ—ฅๅคๆ—ฅ๏ผŒ็ฝ‘ไธŠ็ฝ‘ไธ‹ๅนดๅคๅนดใ€‚
//                  ไฝ†ๆ„ฟ่€ๆญป็”ต่„‘้—ด๏ผŒไธๆ„ฟ้ž ่บฌ่€ๆฟๅ‰๏ผ›
//                  ๅฅ”้ฉฐๅฎ้ฉฌ่ดต่€…่ถฃ๏ผŒๅ…ฌไบค่‡ช่กŒ็จ‹ๅบๅ‘˜ใ€‚
//                  ๅˆซไบบ็ฌ‘ๆˆ‘ๅฟ’็–ฏ็™ซ๏ผŒๆˆ‘็ฌ‘่‡ชๅทฑๅ‘ฝๅคช่ดฑ๏ผ›
//                  ไธ่งๆปก่ก—ๆผ‚ไบฎๅฆน๏ผŒๅ“ชไธชๅฝ’ๅพ—็จ‹ๅบๅ‘˜๏ผŸ
//

//_ooOoo_  
//o8888888o  
//88" . "88  
//(| -_- |)  
// O\ = /O  
//___/`---'\____  
//.   ' \\| |// `.  
/// \\||| : |||// \  
/// _||||| -:- |||||- \  
//| | \\\ - /// | |  
//| \_| ''\---/'' | |  
//\ .-\__ `-` ___/-. /  
//___`. .' /--.--\ `. . __  
//."" '< `.___\_<|>_/___.' >'"".  
//| | : `- \`.;`\ _ /`;.`/ - ` : | |  
//\ \ `-. \_ __\ /__ _/ .-` / /  
//======`-.____`-.___\_____/___.-`____.-'======  
//`=---='  
//  
//         .............................................  
//          ไฝ›ๆ›ฐ๏ผšbugๆณ›ๆปฅ๏ผŒๆˆ‘ๅทฒ็˜ซ็—ช๏ผ


/**
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”โ”“ใ€€ใ€€ใ€€โ”โ”“+ +
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”โ”›โ”ปโ”โ”โ”โ”›โ”ปโ”“ + +
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒ
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒใ€€ใ€€ใ€€โ”ใ€€ใ€€ใ€€โ”ƒ ++ + + +
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ โ–ˆโ–ˆโ–ˆโ–ˆโ”โ–ˆโ–ˆโ–ˆโ–ˆ โ”ƒ+
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒ +
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒใ€€ใ€€ใ€€โ”ปใ€€ใ€€ใ€€โ”ƒ
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒ + +
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”—โ”โ”“ใ€€ใ€€ใ€€โ”โ”โ”›
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒใ€€ใ€€ใ€€โ”ƒ
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒใ€€ใ€€ใ€€โ”ƒ + + + +
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒใ€€ใ€€ใ€€โ”ƒใ€€ใ€€ใ€€ใ€€Code is far away from bug with the animal protecting
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒใ€€ใ€€ใ€€โ”ƒ + ใ€€ใ€€ใ€€ใ€€็ฅžๅ…ฝไฟไฝ‘,ไปฃ็ ๆ— bug
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒใ€€ใ€€ใ€€โ”ƒ
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒใ€€ใ€€ใ€€โ”ƒใ€€ใ€€+
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒใ€€ ใ€€ใ€€โ”—โ”โ”โ”โ”“ + +
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒ ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ฃโ”“
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒ ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”โ”›
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”—โ”“โ”“โ”โ”โ”ณโ”“โ”โ”› + + + +
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”ƒโ”ซโ”ซใ€€โ”ƒโ”ซโ”ซ
*ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ”—โ”ปโ”›ใ€€โ”—โ”ปโ”›+ + + +
*/

//
//   โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–’โ–ˆ    โ–ˆโ–ˆ  โ–„โ–ˆโ–ˆโ–ˆโ–ˆโ–„   โ–ˆโ–ˆ โ–„โ–ˆโ–€       โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•—   โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—
// โ–“โ–ˆโ–ˆ   โ–’ โ–ˆโ–ˆ  โ–“โ–ˆโ–ˆโ–’โ–’โ–ˆโ–ˆโ–€ โ–€โ–ˆ   โ–ˆโ–ˆโ–„โ–ˆโ–’        โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•
// โ–’โ–ˆโ–ˆโ–ˆโ–ˆ โ–‘โ–“โ–ˆโ–ˆ  โ–’โ–ˆโ–ˆโ–‘โ–’โ–“โ–ˆ    โ–„ โ–“โ–ˆโ–ˆโ–ˆโ–„โ–‘        โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ–ˆโ•—
// โ–‘โ–“โ–ˆโ–’  โ–‘โ–“โ–“โ–ˆ  โ–‘โ–ˆโ–ˆโ–‘โ–’โ–“โ–“โ–„ โ–„โ–ˆโ–ˆโ–’โ–“โ–ˆโ–ˆ โ–ˆโ–„        โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘
// โ–‘โ–’โ–ˆโ–‘   โ–’โ–’โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–“ โ–’ โ–“โ–ˆโ–ˆโ–ˆโ–€ โ–‘โ–’โ–ˆโ–ˆโ–’ โ–ˆโ–„       โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•
//  โ–’ โ–‘   โ–‘โ–’โ–“โ–’ โ–’ โ–’ โ–‘ โ–‘โ–’ โ–’  โ–‘โ–’ โ–’โ–’ โ–“โ–’       โ•šโ•โ•โ•โ•โ•โ•  โ•šโ•โ•โ•โ•โ•โ•  โ•šโ•โ•โ•โ•โ•โ•
//  โ–‘     โ–‘โ–‘โ–’โ–‘ โ–‘ โ–‘   โ–‘  โ–’   โ–‘ โ–‘โ–’ โ–’โ–‘
//  โ–‘ โ–‘    โ–‘โ–‘โ–‘ โ–‘ โ–‘ โ–‘        โ–‘ โ–‘โ–‘ โ–‘
//           โ–‘     โ–‘ โ–‘      โ–‘  โ–‘
//                 โ–‘


//                      d*##$.
// zP"""""$e.           $"    $o
//4$       '$          $"      $
//'$        '$        J$       $F
// 'b        $k       $>       $
//  $k        $r     J$       d$
//  '$         $     $"       $~
//   '$        "$   '$E       $
//    $         $L   $"      $F ...
//     $.       4B   $      $$$*"""*b
//     '$        $.  $$     $$      $F
//      "$       R$  $F     $"      $
//       $k      ?$ u*     dF      .$
//       ^$.      $$"     z$      u$$$$e
//        #$b             $E.dW@e$"    ?$
//         #$           .o$$# d$$$$c    ?F
//          $      .d$$#" . zo$>   #$r .uF
//          $L .u$*"      $&$$$k   .$$d$$F
//           $$"            ""^"$$$P"$P9$
//          JP              .o$$$$u:$P $$
//          $          ..ue$"      ""  $"
//         d$          $F              $
//         $$     ....udE             4B
//          #$    """"` $r            @$
//           ^$L        '$            $F
//             RN        4N           $
//              *$b                  d$
//               $$k                 $F
//               $$b                $F
//                 $""               $F
//                 '$                $
//                  $L               $
//                  '$               $
//                   $               $
//

//         โ”Œโ”€โ”       โ”Œโ”€โ”
//      โ”Œโ”€โ”€โ”˜ โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”ดโ”€โ”€โ”
//      โ”‚                 โ”‚
//      โ”‚       โ”€โ”€โ”€       โ”‚
//      โ”‚  โ”€โ”ฌโ”˜       โ””โ”ฌโ”€  โ”‚
//      โ”‚                 โ”‚
//      โ”‚       โ”€โ”ดโ”€       โ”‚
//      โ”‚                 โ”‚
//      โ””โ”€โ”€โ”€โ”         โ”Œโ”€โ”€โ”€โ”˜
//          โ”‚         โ”‚
//          โ”‚         โ”‚
//          โ”‚         โ”‚
//          โ”‚         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
//          โ”‚                        โ”‚
//          โ”‚                        โ”œโ”€โ”
//          โ”‚                        โ”Œโ”€โ”˜
//          โ”‚                        โ”‚
//          โ””โ”€โ”  โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”  โ”Œโ”€โ”€โ”˜
//            โ”‚ โ”€โ”ค โ”€โ”ค       โ”‚ โ”€โ”ค โ”€โ”ค
//            โ””โ”€โ”€โ”ดโ”€โ”€โ”˜       โ””โ”€โ”€โ”ดโ”€โ”€โ”˜
//                ็ฅžๅ…ฝไฟไฝ‘
//                ไปฃ็ ๆ— BUG!
//          Code is far away from bug with the animal protecting

//                               |~~~~~~~|
//                               |       |
//                               |       |
//                               |       |
//                               |       |
//                               |       |
//    |~.\\\_\~~~~~~~~~~~~~~xx~~~         ~~~~~~~~~~~~~~~~~~~~~/_//;~|
//    |  \  o \_         ,XXXXX),                         _..-~ o /  |
//    |    ~~\  ~-.     XXXXX`)))),                 _.--~~   .-~~~   |
//     ~~~~~~~`\   ~\~~~XXX' _/ ';))     |~~~~~~..-~     _.-~ ~~~~~~~
//              `\   ~~--`_\~\, ;;;\)__.---.~~~      _.-~
//                ~-.       `:;;/;; \          _..-~~
//                   ~-._      `''        /-~-~
//                       `\              /  /
//                         |         ,   | |
//                          |  '        /  |
//                           \/;          |
//                            ;;          |
//                            `;   .       |
//                            |~~~-----.....|
//                           | \             \
//                          | /\~~--...__    |
//                          (|  `\       __-\|
//                          ||    \_   /~    |
//                          |)     \~-'      |
//                           |      | \      '
//                           |      |  \    :
//                            \     |  |    |
//                             |    )  (    )
//                              \  /;  /\  |
//                              |    |/   |
//                              |    |   |
//                               \  .'  ||
//                               |  |  | |
//                               (  | |  |
//                               |   \ \ |
//                               || o `.)|
//                               |`\\\\) |
//                               |       |
//                               |       |





//                  ___====-_  _-====___
//            _--^^^#####//      \\#####^^^--_
//         _-^##########// (    ) \\##########^-_
//        -############//  |\^^/|  \\############-
//      _/############//   (@::@)   \\############\_
//     /#############((     \\//     ))#############\
//    -###############\\    (oo)    //###############-
//   -#################\\  / VV \  //#################-
//  -###################\\/      \//###################-
// _#/|##########/\######(   /\   )######/\##########|\#_
// |/ |#/\#/\#/\/  \#/\##\  |  |  /##/\#/  \/\#/\#/\#| \|
// `  |/  V  V  `   V  \#\| |  | |/#/  V   '  V  V  \|  '
//    `   `  `      `   / | |  | | \   '      '  '   '
//                     (  | |  | |  )
//                    __\ | |  | | /__
//                   (vvv(VVV)(VVV)vvv)
//                  ็ฅžๅ…ฝไฟไฝ‘
//                ไปฃ็ ๆ— BUG!
//

//                                                    __----~~~~~~~~~~~------___
//                                   .  .   ~~//====......          __--~ ~~
//                   -.            \_|//     |||\\  ~~~~~~::::... /~
//                ___-==_       _-~o~  \/    |||  \\            _/~~-
//        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
//    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
//  .~       .~       |   \\ -_    /  /-   /   ||      \   /
// /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
// |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
//          '         ~-|      /|    |-~\~~       __--~~
//                      |-~~-_/ |    |   ~\_   _-~            /\
//                           /  \     \__   \/~                \__
//                       _--~ _/ | .-~~____--~-/                  ~~==.
//                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
//                                 -_     ~\      ~~---l__i__i__i--~~_/
//                                 _-~-__   ~)  \--______________--~~
//                               //.-~~~-~_--~- |-------~~~~~~~~
//                                      //.-~~~--\
//                  ็ฅžๅ…ฝไฟไฝ‘
//                ไปฃ็ ๆ— BUG!

//
//      ,----------------,              ,---------,
//         ,-----------------------,          ,"        ,"|
//       ,"                      ,"|        ,"        ,"  |
//      +-----------------------+  |      ,"        ,"    |
//      |  .-----------------.  |  |     +---------+      |
//      |  |                 |  |  |     | -==----'|      |
//      |  |  I LOVE DOS!    |  |  |     |         |      |
//      |  |  Bad command or |  |  |/----|`---=    |      |
//      |  |  C:\>_          |  |  |   ,/|==== ooo |      ;
//      |  |                 |  |  |  // |(((( [33]|    ,"
//      |  `-----------------'  |," .;'| |((((     |  ,"
//      +-----------------------+  ;;  | |         |,"
//         /_)______________(_/  //'   | +---------+
//    ___________________________/___  `,
//   /  oooooooooooooooo  .o.  oooo /,   \,"-----------
//  / ==ooooooooooooooo==.o.  ooo= //   ,`\--{)B     ,"
// /_==__==========__==_ooo__ooo=_/'   /___________,"
//


//
//                 .-~~~~~~~~~-._       _.-~~~~~~~~~-.
//             __.'              ~.   .~              `.__
//           .'//                  \./                  \\`.
//         .'//                     |                     \\`.
//       .'// .-~"""""""~~~~-._     |     _,-~~~~"""""""~-. \\`.
//     .'//.-"                 `-.  |  .-'                 "-.\\`.
//   .'//______.============-..   \ | /   ..-============.______\\`.
// .'______________________________\|/______________________________`.
//
//


// ไบฒ็ˆฑ็š„็ปดๆŠค่€…๏ผš
// ๅฆ‚ๆžœไฝ ๅฐ่ฏ•ไบ†ๅฏน่ฟ™ๆฎต็จ‹ๅบ่ฟ›่กŒโ€˜ไผ˜ๅŒ–โ€™๏ผŒ
// ๅนถ่ฎค่ฏ†ๅˆฐ่ฟ™็งไผๅ›พๆ˜ฏๅคง้”™็‰น้”™๏ผŒ่ฏทๅขžๅŠ 
// ไธ‹้ข่ฟ™ไธช่ฎกๆ•ฐๅ™จ็š„ไธชๆ•ฐ๏ผŒ็”จๆฅๅฏนๅŽๆฅไบบ่ฟ›่กŒ่ญฆๅ‘Š๏ผš
// ๆตช่ดนๅœจ่ฟ™้‡Œ็š„ๆ€ปๆ—ถ้—ด = 39h

/** * ่‡ด็ปˆไบŽๆฅๅˆฐ่ฟ™้‡Œ็š„ๅ‹‡ๆ•ข็š„ไบบ๏ผš
ไฝ ๆ˜ฏ่ขซไธŠๅธ้€‰ไธญ็š„ไบบ๏ผŒ่‹ฑๅ‹‡็š„ใ€ไธ่พžๅŠณ่‹ฆ็š„ใ€ไธ็œ ไธไฟฎ็š„ๆฅไฟฎๆ”น
ๆˆ‘ไปฌ่ฟ™ๆœ€ๆฃ˜ๆ‰‹็š„ไปฃ็ ็š„็ผ–็จ‹้ช‘ๅฃซใ€‚ไฝ ๏ผŒๆˆ‘ไปฌ็š„ๆ•‘ไธ–ไธป๏ผŒไบบไธญไน‹้พ™๏ผŒ
ๆˆ‘่ฆๅฏนไฝ ่ฏด๏ผšๆฐธ่ฟœไธ่ฆๆ”พๅผƒ๏ผŒๆฐธ่ฟœไธ่ฆๅฏน่‡ชๅทฑๅคฑๆœ›๏ผŒๆฐธ่ฟœไธ่ฆ้€ƒ่ตฐ๏ผŒ่พœ่ดŸไบ†่‡ชๅทฑใ€‚
ๆฐธ่ฟœไธ่ฆๅ“ญๅ•ผ๏ผŒๆฐธ่ฟœไธ่ฆ่ฏดๅ†่งใ€‚ๆฐธ่ฟœไธ่ฆ่ฏด่ฐŽๆฅไผคๅฎณ่‡ชๅทฑใ€‚ */




/**
*                      ๆฑŸๅŸŽๅญ . ็จ‹ๅบๅ‘˜ไน‹ๆญŒ
*
*                  ๅๅนด็”Ÿๆญปไธค่Œซ่Œซ๏ผŒๅ†™็จ‹ๅบ๏ผŒๅˆฐๅคฉไบฎใ€‚
*                      ๅƒ่กŒไปฃ็ ๏ผŒBugไฝ•ๅค„่—ใ€‚
*                  ็บตไฝฟไธŠ็บฟๅˆๆ€Žๆ ท๏ผŒๆœไปคๆ”น๏ผŒๅค•ๆ–ญ่‚ ใ€‚
*
*                  ้ข†ๅฏผๆฏๅคฉๆ–ฐๆƒณๆณ•๏ผŒๅคฉๅคฉๆ”น๏ผŒๆ—ฅๆ—ฅๅฟ™ใ€‚
*                      ็›ธ้กพๆ— ่จ€๏ผŒๆƒŸๆœ‰ๆณชๅƒ่กŒใ€‚
*                  ๆฏๆ™š็ฏ็ซ้˜‘็Šๅค„๏ผŒๅคœ้šพๅฏ๏ผŒๅŠ ็ญ็‹‚ใ€‚
*/

//
//                       .::::.
//                     .::::::::.
//                    :::::::::::          FUCK YOU 
//                 ..:::::::::::'
//              '::::::::::::'
//                .::::::::::
//           '::::::::::::::..
//                ..::::::::::::.
//              ``::::::::::::::::
//               ::::``:::::::::'        .:::.
//              ::::'   ':::::'       .::::::::.
//            .::::'      ::::     .:::::::'::::.
//           .:::'       :::::  .:::::::::' ':::::.
//          .::'        :::::.:::::::::'      ':::::.
//         .::'         ::::::::::::::'         ``::::.
//     ...:::           ::::::::::::'              ``::.
//    ```` ':.          ':::::::::'                  ::::..
//                       '.:::::'                    ':'````..


/**********
.--,       .--,
( (  \.---./  ) )
'.__/o   o\__.'
{=  ^  =}
>  -  <
/       \
//       \\
//|   .   |\\
"'\       /'"_.-~^`'-.
\  _  /--'         `
___)( )(___
(((__) (__)))    ้ซ˜ๅฑฑไปฐๆญข,ๆ™ฏ่กŒ่กŒๆญข.่™ฝไธ่ƒฝ่‡ณ,ๅฟƒๅ‘ๅพ€ไน‹ใ€‚


**********/  


/*
::
:;J7, :,                        ::;7:
,ivYi, ,                       ;LLLFS:
:iv7Yi                       :7ri;j5PL
,:ivYLvr                    ,ivrrirrY2X,
:;[email protected]:                :ivu@kexianli.
:iL7::,:::iiirii:ii;::::,,irvF7rvvLujL7ur
ri::,:,::i:iiiiiii:i:irrv177JX7rYXqZEkvv17
;i:, , ::::iirrririi:i:::iiir2XXvii;L8OGJr71i
:,, ,,:   ,::[email protected]:i:::j1jri7ZBOS7ivv,
,::,    ::rv77iiiriii:iii:i::,[email protected]
,,      ,, ,:ir7ir::,:::i;ir:::i:i::rSGGYri712:
:::  ,v7r:: ::rrv77:, ,, ,:i7rrii:::::, ir7ri7Lri
,     2OBBOi,iiir;r::        ,irriiii::,, ,iv7Luur:
,,     i78MBBi,:,:::,:,  :7FSL: ,iriii:::i::,,:rLqXv::
:      iuMMP: :,:::,:ii;2GY7OBB0viiii:i:iii:i:::iJqL;::
,     ::::i   ,,,,, ::LuBBu BBBBBErii:i:i:i:i:i:i:r77ii
,       :       , ,,:::rruBZ1MBBqi, :,,,:::,::::::iiriri:
,               ,,,,::::i:  @arqiao.       ,:,, ,:::ii;i7:
:,       rjujLYLi   ,,:::::,:::::::::,,   ,:i,:,,,,,::i:iii
::      BBBBBBBBB0,    ,,::: , ,:::::: ,      ,,,, ,,:::::::
i,  ,  ,8BMMBBBBBBi     ,,:,,     ,,, , ,   , , , :,::ii::i::
:      iZMOMOMBBM2::::::::::,,,,     ,,,,,,:,,,::::i:irr:i:::,
i   ,,:;u0MBMOG1L:::i::::::  ,,,::,   ,,, ::::::i:i:iirii:i:i:
:    ,iuUuuXUkFu7i:iii:i:::, :,:,: ::::::::i:i:::::iirr7iiri::
:     :[email protected]:::::, ,:ii:::::::i:::::i::,::::iirrriiiri::,
:      5BMBBBBBBSr:,::rv2kuii:::iii::,:i:,, , ,,:,:i@petermu.,
, :r50EZ8MBBBBGOBBBZP7::::i::,:::::,: :,:,::i;rrririiii::
:jujYY7LS0ujJL7r::,::i::,::::::::::::::iirirrrrrrr:ii:
,:  :@kevensun.:,:,,,::::i:i:::::,,::::::iir;ii;7v77;ii;i,
,,,     ,,:,::::::i:iiiii:i::::,, ::::[email protected];7:i,
, , ,,,:,,::::::::iiiiiiiiii:,:,:::::::::iiir;ri7vL77rrirri::
:,, , ::::::::i:::i:::i:i::,,,,,:,::i:i:::iir;@Secbone.ii:::

*/

/**
* โ”Œโ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”
* โ”‚Escโ”‚   โ”‚ F1โ”‚ F2โ”‚ F3โ”‚ F4โ”‚ โ”‚ F5โ”‚ F6โ”‚ F7โ”‚ F8โ”‚ โ”‚ F9โ”‚F10โ”‚F11โ”‚F12โ”‚ โ”‚P/Sโ”‚S Lโ”‚P/Bโ”‚  โ”Œโ”    โ”Œโ”    โ”Œโ”
* โ””โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”˜  โ””โ”˜    โ””โ”˜    โ””โ”˜
* โ”Œโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”
* โ”‚~ `โ”‚! 1โ”‚@ 2โ”‚# 3โ”‚$ 4โ”‚% 5โ”‚^ 6โ”‚& 7โ”‚* 8โ”‚( 9โ”‚) 0โ”‚_ -โ”‚+ =โ”‚ BacSp โ”‚ โ”‚Insโ”‚Homโ”‚PUpโ”‚ โ”‚N Lโ”‚ / โ”‚ * โ”‚ - โ”‚
* โ”œโ”€โ”€โ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”ค โ”œโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ค โ”œโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ค
* โ”‚ Tab โ”‚ Q โ”‚ W โ”‚ E โ”‚ R โ”‚ T โ”‚ Y โ”‚ U โ”‚ I โ”‚ O โ”‚ P โ”‚{ [โ”‚} ]โ”‚ | \ โ”‚ โ”‚Delโ”‚Endโ”‚PDnโ”‚ โ”‚ 7 โ”‚ 8 โ”‚ 9 โ”‚   โ”‚
* โ”œโ”€โ”€โ”€โ”€โ”€โ”ดโ”ฌโ”€โ”€โ”ดโ”ฌโ”€โ”€โ”ดโ”ฌโ”€โ”€โ”ดโ”ฌโ”€โ”€โ”ดโ”ฌโ”€โ”€โ”ดโ”ฌโ”€โ”€โ”ดโ”ฌโ”€โ”€โ”ดโ”ฌโ”€โ”€โ”ดโ”ฌโ”€โ”€โ”ดโ”ฌโ”€โ”€โ”ดโ”ฌโ”€โ”€โ”ดโ”ฌโ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”ค โ””โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”˜ โ”œโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ค + โ”‚
* โ”‚ Caps โ”‚ A โ”‚ S โ”‚ D โ”‚ F โ”‚ G โ”‚ H โ”‚ J โ”‚ K โ”‚ L โ”‚: ;โ”‚" 'โ”‚ Enter  โ”‚               โ”‚ 4 โ”‚ 5 โ”‚ 6 โ”‚   โ”‚
* โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค     โ”Œโ”€โ”€โ”€โ”     โ”œโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ค
* โ”‚ Shift  โ”‚ Z โ”‚ X โ”‚ C โ”‚ V โ”‚ B โ”‚ N โ”‚ M โ”‚< ,โ”‚> .โ”‚? /โ”‚  Shift   โ”‚     โ”‚ โ†‘ โ”‚     โ”‚ 1 โ”‚ 2 โ”‚ 3 โ”‚   โ”‚
* โ”œโ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”ดโ”€โ”ฌโ”€โ”ดโ”€โ”€โ”ฌโ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”ฌโ”ดโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ดโ”ฌโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”ค โ”Œโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ” โ”œโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ค Eโ”‚โ”‚
* โ”‚ Ctrlโ”‚    โ”‚Alt โ”‚         Space         โ”‚ Altโ”‚    โ”‚    โ”‚Ctrlโ”‚ โ”‚ โ† โ”‚ โ†“ โ”‚ โ†’ โ”‚ โ”‚   0   โ”‚ . โ”‚โ†โ”€โ”˜โ”‚
* โ””โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”˜
*/

/**
**************************************************************
*                                                            *
*   .=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-.       *
*    |                     ______                     |      *
*    |                  .-"      "-.                  |      *
*    |                 /            \                 |      *
*    |     _          |              |          _     |      *
*    |    ( \         |,  .-.  .-.  ,|         / )    |      *
*    |     > "=._     | )(__/  \__)( |     _.=" <     |      *
*    |    (_/"=._"=._ |/     /\     \| _.="_.="\_)    |      *
*    |           "=._"(_     ^^     _)"_.="           |      *
*    |               "=\__|IIIIII|__/="               |      *
*    |              _.="| \IIIIII/ |"=._              |      *
*    |    _     _.="_.="\          /"=._"=._     _    |      *
*    |   ( \_.="_.="     `--------`     "=._"=._/ )   |      *
*    |    > _.="                            "=._ <    |      *
*    |   (_/                                    \_)   |      *
*    |                                                |      *
*    '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-='      *
*                                                            *
*           LASCIATE OGNI SPERANZA, VOI CH'ENTRATE           *
**************************************************************
*/

/**
* ้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚ใ€€้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚
* ้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚ใ€€ใ€€ใ€€ใ€€ใ€€้ ‚้ ‚ใ€€ใ€€ใ€€ใ€€ใ€€
* ใ€€ใ€€ใ€€้ ‚้ ‚ใ€€ใ€€ใ€€้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚
* ใ€€ใ€€ใ€€้ ‚้ ‚ใ€€ใ€€ใ€€้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚้ ‚
* ใ€€ใ€€ใ€€้ ‚้ ‚ใ€€ใ€€ใ€€้ ‚้ ‚ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€้ ‚้ ‚
* ใ€€ใ€€ใ€€้ ‚้ ‚ใ€€ใ€€ใ€€้ ‚้ ‚ใ€€ใ€€้ ‚้ ‚้ ‚ใ€€ใ€€้ ‚้ ‚
* ใ€€ใ€€ใ€€้ ‚้ ‚ใ€€ใ€€ใ€€้ ‚้ ‚ใ€€ใ€€้ ‚้ ‚้ ‚ใ€€ใ€€้ ‚้ ‚
* ใ€€ใ€€ใ€€้ ‚้ ‚ใ€€ใ€€ใ€€้ ‚้ ‚ใ€€ใ€€้ ‚้ ‚้ ‚ใ€€ใ€€้ ‚้ ‚
* ใ€€ใ€€ใ€€้ ‚้ ‚ใ€€ใ€€ใ€€้ ‚้ ‚ใ€€ใ€€้ ‚้ ‚้ ‚ใ€€ใ€€้ ‚้ ‚
* ใ€€ใ€€ใ€€้ ‚้ ‚ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€้ ‚้ ‚้ ‚ใ€€
* ใ€€ใ€€ใ€€้ ‚้ ‚ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€้ ‚้ ‚ใ€€้ ‚้ ‚ใ€€้ ‚้ ‚
* ใ€€้ ‚้ ‚้ ‚้ ‚ใ€€ใ€€ใ€€้ ‚้ ‚้ ‚้ ‚้ ‚ใ€€้ ‚้ ‚้ ‚้ ‚้ ‚
* ใ€€้ ‚้ ‚้ ‚้ ‚ใ€€ใ€€ใ€€้ ‚้ ‚้ ‚้ ‚ใ€€ใ€€ใ€€้ ‚้ ‚้ ‚้ ‚
*/


/*



.. .vr       
qBMBBBMBMY     
8BBBBBOBMBMv    
iMBMM5vOY:BMBBv        
.r,             OBM;   .: rBBBBBY     
vUL             7BB   .;7. LBMMBBM.   
.@Wwz.           :uvir .i:.iLMOMOBM..  
vv::r;             iY. ...rv,@arqiao. 
Li. i:             v:.::::7vOBBMBL.. 
,i7: vSUi,         :M7.:.,:u08OP. .  
.N2k5u1ju7,..     BMGiiL7   ,i,i.  
:rLjFYjvjLY7r::.  ;v  vr... rE8q;.:,, 
751jSLXPFu5uU@guohezou.,1vjY2E8@Yizero.    
BB:FMu rkM8Eq0PFjF15FZ0Xu15F25uuLuu25Gi.   
ivSvvXL    :v58ZOGZXF2UUkFSFkU1u125uUJUUZ,   
:@kevensun.      ,iY20GOXSUXkSuS2F5XXkUX5SEv.  
.:i0BMBMBBOOBMUi;,        ,;8PkFP5NkPXkFqPEqqkZu.  
.rqMqBBMOMMBMBBBM .           @kexianli.S11kFSU5q5   
.7BBOi1L1MM8BBBOMBB..,          8kqS52XkkU1Uqkk1kUEJ   
.;MBZ;iiMBMBMMOBBBu ,           1OkS1F1X5kPP112F51kU   
.rPY  OMBMBBBMBB2 ,.          rME5SSSFk1XPqFNkSUPZ,.
;;JuBML::r:.:.,,        SZPX0SXSP5kXGNP15UBr.
L,    :@sanshao.      :MNZqNXqSqXk2E0PSXPE .
viLBX.,,v8Bj. i:r7:,     2Zkqq0XXSNN0NOXXSXOU 
:r2. rMBGBMGi .7Y, 1i::i   vO0PMNNSXXEqP@Secbone.
.i1r. .jkY,    vE. iY....  20Fq0q5X5F1S2F22uuv1M; 


ๅˆ็œ‹ๆบ็ ,็œ‹ไฝ ๅฆนๅฆนๅ‘€!


*/


/*
__
,-~ยจ^  ^ยจ-,           _,
/          / ;^-._...,ยจ/
/          / /         /
/          / /         /
/          / /         /
/,.-:''-,_ / /         /
_,.-:--._ ^ ^:-._ __../
/^         / /ยจ:.._ยจ__.;
/          / /      ^  /
/          / /         /
/          / /         /
/_,.--:^-._/ /         /
^            ^ยจยจ-.___.:^  (R) - G33K

*/


/*
___                _
/ __|___  ___  __ _| |___
| (_ / _ \/ _ \/ _` |   -_)
\___\___/\___/\__, |_\___|
|___/

*/

/*
_.-"""""-._         _.-"""""-._         _.-"""""-._
,'           `.     ,'           `.     ,'           `.
/               \   /               \   /               \
|                 | |                 | |                 |
|                   |                   |                   |
|                   |                   |                   |
|             _.-"|"|"-._         _.-"|"|"-._             |
\          ,'   /   \   `.     ,'   /   \   `.          /
`.       /   ,'     `.   \   /   ,'     `.   \       ,'
`-..__|..-'         `-..|_|..-'         `-..|__..-'
|                   |                   |
|                   |                   |
|                 | |                 |
\               /   \               /
`.           ,'     `.           ,'
`-..___..-'         `-..___..-'

*/


/*
_
\"-._ _.--"~~"--._
\   "            ^.    ___
/                  \.-~_.-~
.-----'     /\/"\ /~-._      /
/  __      _/\-.__\L_.-/\     "-.
/.-"  \    ( ` \_o>"<o_/  \  .--._\
/'      \    \:     "     :/_/     "`
/  /\ "\    ~    /~"
\ I  \/]"-._ _.-"[
___ \|___/ ./    l   \___   ___
.--v~   "v` ( `-.__   __.-' ) ~v"   ~v--.
.-{   |     :   \_    "~"    _/   :     |   }-.
/   \  |           ~-.,___,.-~           |  /   \
]     \ |                                 | /     [
/\     \|     :                     :     |/     /\
/  ^._  _K.___,^                     ^.___,K_  _.^  \
/   /  "~/  "\                           /"  \~"  \   \
/   /    /     \ _          :          _ /     \    \   \
.^--./    /       Y___________l___________Y       \    \.--^.
[    \   /        |        [/    ]        |        \   /    ]
|     "v"         l________[____/]________j  -Row   }r"     /
}------t          /                       \       /`-.     /
|      |         Y                         Y     /    "-._/
}-----v'         |         :               |     7-.     /
|   |_|          |         l               |    / . "-._/
l  .[_]          :          \              :  r[]/_.  /
\_____]                     "--.             "-.____/

"Dragonball Z"
---Row

*/


/*
MMMMM
MMMMMM
MMMMMMM
MMMMMMMM     .
MMMMMMMMM
HMMMMMMMMMM
MMMMMMMMMMMM  M
MMMMMMMMMMMMM  M
MMMMMMMMMMMMM  M
MMMMMMMMMMMMM:
oMMMMMMMMMMMMMM
.MMMMMMMMMMMMMMo           MMMMMMMMMMMMMMM M
MMMMMMMMMMMMMMMMMMMMMMMMMMM      MMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMM.  oMMMMMMMMMMMMMMM.M
MMMMMMMMMMMMMMMMMMMMMMMMMMMM  MMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
oMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM:                     H
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM                  .         MMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM              M       MMMMMM
.MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM          M   MMMMMMMMMM
MM.      MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM       M MMMMMMMMMMMM
MM    MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM    .MMMMMMMMMMMMMM
MM  MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MM MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
.MMMMMMMMM MMMMMMMMMMMMMMMMMMMMMMMM.MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
HMMMMMMMMMMMMMMMMMMMMM.MMMMMMMMM.MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMM MMM.oMMMMMMM..MMMMMMMMM:MMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMM MM..MMMMMMM...MMMMMMM. MMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMM ..MMMMMM...MMMMMM ..MMMMMMMMMMMMMMMMMMM
MMMMMMM:M.MMM.M.. MMMMM M..MMMMM...MMMMMMMMMMMMMMMMMM  MMM
MMMM. .M..MM.M...MMMMMM..MMMMM.. MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM .
MMMM..M....M.....:MMM .MMMMMM..MMMMMMM...MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMM.M.. ...M......MM.MMMMM.......MHM.M  .MMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMM..MM. . MMM.....MMMMMM.M.....M ..MM..M MMMMMMMMMMMMMMMMMMM
.MMMMMHMM. ..MMMM. MMM............o..... . .MMMMMMMMMMMMMMM
MMM. M... .........................M..:.MMMMMMMMMMMM
oMMM............ .................M.M.MMMMMMMMM
.....MM........................ . MMMMMM
M.....M.....................o.MM.MMMMMMMM.
M........................M.. ...MMMMMMMMMMMMMo
:....MMM..............MMM..oMMMMMMM
M...MMM.............MMMMMMM
.............:MMMMMMMM
M..... MMM.....M
M M.............
................M
ooM.................MM  MoMMMMMoooM
MMoooM......................MoooooooH..oMM
MHooooMoM.....................MMooooooM........M
oooooooMoooM......... o........MoooooooM............
Mooooooooooo.......M.........Moooooooo:..............M
MooMoooooooooM...M........:Mooooooooooo:..............M
M..oooooooooooo .........Mooooooooooooooo..............M
M...Mooo:oooooooo.M....ooooooooooooooooooo..M...........M
...oooooMoooooooM..Mooooooooooooo:oooooooM.M...........M.
M...ooooooMoo:ooooMoooooooooooooHoooooooooH:M. ...........:
M..MoooooooMoooooooooooooooooo:ooooooMooooMoM..............M
M..ooooooooooMooooooooooooooHoooooooMooHooooM...............M
...ooooooooooooooooooo:MooooooooooooooMoMoooM................
M...oooooooooooooooooooooooooooooooooooooMooMM................M
...MooooooooooooooooooooooooooooooooooooooooMo ................
...MooooooooooooooooooooooooooooooooooooooooM M................M
M...ooooooooooooooooooooooooooooooooooooooooM   ................M
...MoooooooooooooooooooooooooooooooooooooooMM   .:...............
.....MooooooooooooooooooooooooooooooooooooMoo       .............M
M...... ooooooooooooooooooooooooooooooooooooM       M..............M
M........MooooMMM MM MM  MMMMMMMMMooooooooM         M...............M
.........HM     M:  MM :MMMMMM          M           M...............
M..........M     M   MoM M                           M................M
M.........:M  MoH  M M M MooooHoooMM.   M             M...............M
M..........Moooo MMooM    oooooMooooooooM              M..............H
M.........MooooM  Mooo  : ooooooMooooMoooM              M........ . .o.M
H..  .....ooooo   oooo  M MooooooooooooooM               M... MMMMMMMMMMM
MMMMMMMMMMooooM M oooo  .  ooooooMooooooooM              .MMMMMMMMMMMMMMM
MMMMMMMMMMooooH : ooooH    oooooooooooooooo               MMMMMMMMMMMMMMM
MMMMMMMMMMoooo    ooooM    Moooooooooooooooo              .MMMMMMMMMMMMMMM
MMMMMMMMMMoooo    ooooM    MooooooooooooooooM              MMMMMMMMMMMMMMM
MMMMMMMMMMoooM    ooooM     ooooooooooooooooo               MMMMMMMMMMM:M
MMMMMMMMMMoooM   MooooM     oooooooooooMoooooo               MH...........
. ......Mooo.   MooooM     oooooooooooooooooo              M............M
M.M......oooo    MooooM     Moooooooooooooooooo:           .........M.....
M.M.....Moooo    MooooM      ooooooooooooooooooM            .M............
.......MooooH    MooooM      oooooooooMoooooooooo          M..o...M..o....M
.o....HMooooM    MooooH      MooooooooMooooooooooM          .:M...M.......M
M..M.....MoooM    :oooo:    .MooooooooHooMoooooooooM         M M... ..oM.M
M...M.:.Mooo. MMMMooooo   oooooooooooMoooooooooooooM          ....M. M
M:M..o.Moooooooooooooo MooooooooooooooMooooooooooooM          .Mo
MooooooooooooooMooooooooooooMoMoooooooooooooo
Mooooooooooooooo:ooooooooooooooooooooooooooooo
ooooooooooooooooMooooooooooMoooooooooooooooooo
ooooooooooooooooMoooooooooooMooooooooooooooooHo
ooMooooooooooooooMoooooooooooooooooooooooooooMoM
MooMoooooooooooooo.ooooooooooooooooooooooooooo:oM
MoooooooooooooooooooooooooooooooooooooooooooooooM
MoooMooooooooooooooMooooooooooooooooooooooooooooo.
MoooMooooooooooooooMoooooooooooooooooooooooooMooooM
MooooooooooooooooooMoooooooooooooooooooooooooMoooooM
MooooMoooooooooooooMoooooooooooooooooooooooooMoHooooM
ooooooMooooooooooooooooooooooooooooooooooooooooMoMoooM
MooooooooooooooooooooMooooooooooooooooooooooooooMoooooH:
MoooooooMooooooooooooMoooooooooooooooooooooooooooooHoooM
MooooooooMoooooooooooMoooooooooooooooooooooooooMoooMooooM
Moooooooooooooooooooooooooooooooooooooooooooooo.oooMooooo
MoooooooooooooooooooooooooooooooooooooooooooooMoooooooooM
MooooooooooooooooooooMoooooooooooooooooooooooooooooooooM
MooooooooooooooooooooMHooooooooooooooooooooMoooo:ooooo
MMooooooooooooooooooMoMHoooooooooooooooooooooooMooooo
MMoooooooooooooooMMooo MMooooooooooooooooooooooooooM
MMMoooooooooooooMooooo  oooooooooooooooooooooMooooo
MooMMoooooooooMoooMMoM  ooooHooooooooooooooooMooooM
MooooMooooooMooooMoooM  MoooooMoooooooooooooMooooo
ooooooMMooooooooMooooM  MoooooooooMooooooooooooooM
HooooooMoooooooMooooM    HoooooooHooMooooooooooooo
oooMoooooooooHoooM         MoooooooooMoooooooooM
HooooooooooooHM             MooooooooMMoooooooM
MMMMMMMMMMMMMM                Moooooo:MooooHMM
MMMMMMM: ...                  MMMMMMMMMMMMMM
M............M                  MMMMMMMMM ....
M.MM..........                  M.............M
M ..............MM                 M..............
MMMMM............MMMM                 ..MMMMMMMM ....M
MMMMMMMMMMMMMMMMMMMMMMMM               MMMMMMMMMMMMM...M
.MMMMMMMMMMMMMMMMMMMMMMMMMM               MMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMM                MMMMMMMMMMMMMMMMMMM
:MMMMMMMMMMMMMMMMMMH                     MMMMMMMMMMMMMMMMMMM
By EBEN Jรฉrรดme                        MMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMM
HMMMMMM

*/



/*
quu..__
$$$b  `---.__
"$$b        `--.                          ___.---uuudP
`$$b           `.__.------.__     __.---'      $$$$"              .
"$b          -'            `-.-'            $$$"              .'|
".                                       d$"             _.'  |
`.   /                              ..."             .'     |
`./                           ..::-'            _.'       |
/                         .:::-'            .-'         .'
:                          ::''\          _.'            |
.' .-.             .-.           `.      .'               |
: /'$$|           .@"$\           `.   .'              _.-'
.'|$u$$|          |$$,$$|           |  <            _.-'
| `:$$:'          :$$$$$:           `.  `.       .-'
:                  `"--'             |    `-.     \
:##.       ==             .###.       `.      `.    `\
|##:                      :###:        |        >     >
|#'     `..'`..'          `###'        x:      /     /
\                                   xXX|     /    ./
\                                xXXX'|    /   ./
/`-.                                  `.  /   /
:    `-  ...........,                   | /  .'
|         ``:::::::'       .            |<    `.
|             ```          |           x| \ `.:``.
|                         .'    /'   xXX|  `:`M`M':.
|    |                    ;    /:' xXXX'|  -'MMMMM:'
`.  .'                   :    /:'       |-'MMMM.-'
|  |                   .'   /'        .'MMM.-'
`'`'                   :  ,'          |MMM<
|                     `'            |tbap\
\                                  :MM.-'
\                 |              .''
\.               `.            /
/     .:::::::.. :           /
|     .:::::::::::`.         /
|   .:::------------\       /
/   .''               >::'  /
`',:                 :    .'
`:.:'


*/



/*
11111111111111111111111111111111111111001111111111111111111111111
11111111111111111111111111111111111100011111111111111111111111111
11111111111111111111111111111111100001111111111111111111111111111
11111111111111111111111111111110000111111111111111111111111111111
11111111111111111111111111111000000111111111111111111111111111111
11111111111111111111111111100000011110001100000000000000011111111
11111111111111111100000000000000000000000000000000011111111111111
11111111111111110111000000000000000000000000000011111111111111111
11111111111111111111111000000000000000000000000000000000111111111
11111111111111111110000000000000000000000000000000111111111111111
11111111111111111100011100000000000000000000000000000111111111111
11111111111111100000110000000000011000000000000000000011111111111
11111111111111000000000000000100111100000000000001100000111111111
11111111110000000000000000001110111110000000000000111000011111111
11111111000000000000000000011111111100000000000000011110001111111
11111110000000011111111111111111111100000000000000001111100111111
11111111000001111111111111111111110000000000000000001111111111111
11111111110111111111111111111100000000000000000000000111111111111
11111111111111110000000000000000000000000000000000000111111111111
11111111111111111100000000000000000000000000001100000111111111111
11111111111111000000000000000000000000000000111100000111111111111
11111111111000000000000000000000000000000001111110000111111111111
11111111100000000000000000000000000000001111111110000111111111111
11111110000000000000000000000000000000111111111110000111111111111
11111100000000000000000001110000001111111111111110001111111111111
11111000000000000000011111111111111111111111111110011111111111111
11110000000000000001111111111111111100111111111111111111111111111
11100000000000000011111111111111111111100001111111111111111111111
11100000000001000111111111111111111111111000001111111111111111111
11000000000001100111111111111111111111111110000000111111111111111
11000000000000111011111111111100011111000011100000001111111111111
11000000000000011111111111111111000111110000000000000011111111111
11000000000000000011111111111111000000000000000000000000111111111
11001000000000000000001111111110000000000000000000000000001111111
11100110000000000001111111110000000000000000111000000000000111111
11110110000000000000000000000000000000000111111111110000000011111
11111110000000000000000000000000000000001111111111111100000001111
11111110000010000000000000000001100000000111011111111110000001111
11111111000111110000000000000111110000000000111111111110110000111
11111110001111111100010000000001111100000111111111111111110000111
11111110001111111111111110000000111111100000000111111111111000111
11111111001111111111111111111000000111111111111111111111111100011
11111111101111111111111111111110000111111111111111111111111001111
11111111111111111111111111111110001111111111111111111111100111111
11111111111111111111111111111111001111111111111111111111001111111
11111111111111111111111111111111100111111111111111111111111111111
11111111111111111111111111111111110111111111111111111111111111111


*/



/*
.....'',;;::cccllllllllllllcccc:::;;,,,''...'',,'..
..';cldkO00KXNNNNXXXKK000OOkkkkkxxxxxddoooddddddxxxxkkkkOO0XXKx:.
.':ok0KXXXNXK0kxolc:;;,,,,,,,,,,,;;,,,''''''',,''..              .'lOXKd'
.,lx00Oxl:,'............''''''...................    ...,;;'.             .oKXd.
.ckKKkc'...'',:::;,'.........'',;;::::;,'..........'',;;;,'.. .';;'.           'kNKc.
.:kXXk:.    ..       ..................          .............,:c:'...;:'.         .dNNx.
:0NKd,          .....''',,,,''..               ',...........',,,'',,::,...,,.        .dNNx.
.xXd.         .:;'..         ..,'             .;,.               ...,,'';;'. ...       .oNNo
.0K.         .;.              ;'              ';                      .'...'.           .oXX:
.oNO.         .                 ,.              .     ..',::ccc:;,..     ..                lXX:
.dNX:               ......       ;.                'cxOKK0OXWWWWWWWNX0kc.                    :KXd.
.l0N0;             ;d0KKKKKXK0ko:...              .l0X0xc,...lXWWWWWWWWKO0Kx'                   ,ONKo.
.lKNKl...'......'. .dXWN0kkk0NWWWWWN0o.            :KN0;.  .,cokXWWNNNNWNKkxONK: .,:c:.      .';;;;:lk0XXx;
:KN0l';ll:'.         .,:lodxxkO00KXNWWWX000k.       oXNx;:okKX0kdl:::;'',;coxkkd, ...'. ...'''.......',:lxKO:.
oNNk,;c,'',.                      ...;xNNOc,.         ,d0X0xc,.     .dOd,           ..;dOKXK00000Ox:.   ..''dKO,
'KW0,:,.,:..,oxkkkdl;'.                'KK'              ..           .dXX0o:'....,:oOXNN0d;.'. ..,lOKd.   .. ;KXl.
;XNd,;  ;. l00kxoooxKXKx:..ld:         ;KK'                             .:dkO000000Okxl;.   c0;      :KK;   .  ;XXc
'XXdc.  :. ..    '' 'kNNNKKKk,      .,dKNO.                                   ....       .'c0NO'      :X0.  ,.  xN0.
.kNOc'  ,.      .00. ..''...      .l0X0d;.             'dOkxo;...                    .;okKXK0KNXx;.   .0X:  ,.  lNX'
,KKdl  .c,    .dNK,            .;xXWKc.                .;:coOXO,,'.......       .,lx0XXOo;...oNWNXKk:.'KX;  '   dNX.
:XXkc'....  .dNWXl        .';l0NXNKl.          ,lxkkkxo' .cK0.          ..;lx0XNX0xc.     ,0Nx'.','.kXo  .,  ,KNx.
cXXd,,;:, .oXWNNKo'    .'..  .'.'dKk;        .cooollox;.xXXl     ..,cdOKXXX00NXc.      'oKWK'     ;k:  .l. ,0Nk.
cXNx.  . ,KWX0NNNXOl'.           .o0Ooldk;            .:c;.':lxOKKK0xo:,.. ;XX:   .,lOXWWXd.      . .':,.lKXd.
lXNo    cXWWWXooNWNXKko;'..       .lk0x;       ...,:ldk0KXNNOo:,..       ,OWNOxO0KXXNWNO,        ....'l0Xk,
.dNK.   oNWWNo.cXK;;oOXNNXK0kxdolllllooooddxk00KKKK0kdoc:c0No        .'ckXWWWNXkc,;kNKl.          .,kXXk,
'KXc  .dNWWX;.xNk.  .kNO::lodxkOXWN0OkxdlcxNKl,..        oN0'..,:ox0XNWWNNWXo.  ,ONO'           .o0Xk;
.ONo    oNWWN0xXWK, .oNKc       .ONx.      ;X0.          .:XNKKNNWWWWNKkl;kNk. .cKXo.           .ON0;
.xNd   cNWWWWWWWWKOkKNXxl:,'...;0Xo'.....'lXK;...',:lxk0KNWWWWNNKOd:..   lXKclON0:            .xNk.
.dXd   ;XWWWWWWWWWWWWWWWWWWNNNNNWWNNNNNNNNNWWNNNNNNWWWWWNXKNNk;..        .dNWWXd.             cXO.
.xXo   .ONWNWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWNNK0ko:'..OXo          'l0NXx,              :KK,
.OXc    :XNk0NWXKNWWWWWWWWWWWWWWWWWWWWWNNNX00NNx:'..       lXKc.     'lONN0l.              .oXK:
.KX;    .dNKoON0;lXNkcld0NXo::cd0NNO:;,,'.. .0Xc            lXXo..'l0NNKd,.              .c0Nk,
:XK.     .xNX0NKc.cXXl  ;KXl    .dN0.       .0No            .xNXOKNXOo,.               .l0Xk;.
.dXk.      .lKWN0d::OWK;  lXXc    .OX:       .ONx.     . .,cdk0XNXOd;.   .'''....;c:'..;xKXx,
.0No         .:dOKNNNWNKOxkXWXo:,,;ONk;,,,,,;c0NXOxxkO0XXNXKOdc,.  ..;::,...;lol;..:xKXOl.
,XX:             ..';cldxkOO0KKKXXXXXXXXXXKKKKK00Okxdol:;'..   .';::,..':llc,..'lkKXkc.
:NX'    .     ''            ..................             .,;:;,',;ccc;'..'lkKX0d;.
lNK.   .;      ,lc,.         ................        ..,,;;;;;;:::,....,lkKX0d:.
.oN0.    .'.      .;ccc;,'....              ....'',;;;;;;;;;;'..   .;oOXX0d:.
.dN0.      .;;,..       ....                ..''''''''....     .:dOKKko;.
lNK'         ..,;::;;,'.........................           .;d0X0kc'.
.xXO'                                                 .;oOK0x:.
.cKKo.                                    .,:oxkkkxk0K0xc'.
.oKKkc,.                         .';cok0XNNNX0Oxoc,.
.;d0XX0kdlc:;,,,',,,;;:clodkO0KK0Okdl:,'..
.,coxO0KXXXXXXXKK0OOxdoc:,..
...

*/


/*

/88888888888888888888888888\
|88888888888888888888888888/
|~~____~~~~~~~~~"""""""""|
/ \_________/"""""""""""""\
/  |              \         \
/   |  88    88     \         \
/    |  88    88      \         \
/    /                  \        |
/     |   ________        \       |
\     |   \______/        /       |
/"\         \     \____________     /        |
| |__________\_        |  |        /        /
/""""\           \_------'  '-------/       --
\____/,___________\                 -------/
------*            |                    \
||               |                     \
||               |                 ^    \
||               |                | \    \
||               |                |  \    \
||               |                |   \    \
\|              /                /"""\/    /
-------------                |    |    /
|\--_                        \____/___/
|   |\-_                       |
|   |   \_                     |
|   |     \                    |
|   |      \_                  |
|   |        ----___           |
|   |               \----------|
/   |                     |     ----------""\
/"\--"--_|                     |               |  \
|_______/                      \______________/    )
\___/
*/

/*
*     ,MMM8&&&.            *
MMMM88&&&&&    .
MMMM88&&&&&&&
*           MMM88&&&&&&&&
MMM88&&&&&&&&
'MMM88&&&&&&'
'MMM8&&&'      *    
/\/|_    __/\\
/    -\  /-   ~\  .              '
\    =_YT_ =   /
/==*(`    `\ ~ \
/     \     /    `\
|     |     ) ~   (
/       \   /     ~ \
\       /   \~     ~/
jgs_/\_/\__  _/_/\_/\__~__/_/\_/\_/\_/\_/\_
|  |  |  | ) ) |  |  | ((  |  |  |  |  |  |
|  |  |  |( (  |  |  |  \\ |  |  |  |  |  |
|  |  |  | )_) |  |  |  |))|  |  |  |  |  |     Joan Stark
|  |  |  |  |  |  |  |  (/ |  |  |  |  |  |
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |
*/


/*
............HIIMHIMHMMHMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM:.............
...........MMMI:MII:MIHMHMMMMMHMMMMIMMMIMMMMMMMMMMMMMM.............
.........:MMMI:M::HM::MIHHHM:IM:MHM:IMH:IMMMIIMMMHMMMH:............
........:MMMHHM::MMI:HH:MM:I:M:MMMH:IMH:IMM::MH:MM:MM:M............
.......MMMMHMM:MMIMHMII:MM:IIIM:MHMIMMM:MMIIH::MH:HM:M............
...... :MIMMMMMMMMMHMMHMM:HHMHMMMMIMHMMMMHMHMIHIHM::MMI............
.......M:MMMMMMMMMMMMHMMMMMMMMHMMMMMMMMMMHMMMHMMIMHMMMM:...........
.......HHMMMMMMMMMMMMMMMMIMMMM.MMHMMMMHMMMMMMMMMMMIMHMMI...........
........MMMIMMMMMMMMMMIHMIMIM:.M:HMM:MIHMMMMMMMMMMMMMMMI...........
........MM.MMMMMMMMMMMH:MMMHM:.M.:MM.M.HMMMHMMMMMMMMMMMI...........
........MM.MMMMMMMMMMH::M.M.M..M..MM:M.IIMH:MMMMMMMMMMMI...........
........M:.MM:MMMMMMM:.I..:.I..H..IM:I.I.M.IMHMMMMMMMMMI...........
........M..MMMHMMMMM.:HI:HHH......H....II..:MMMMMMMHMM:...........
...........MM.MIMMMM.:H: .::I........ ...:IH:.MMMMMM:MMI...........
...........:H..MMMIM.M.:...:I.........: ..::HHHMMMMIMMMH...........
............H..IMM:I:..I:..:..........I:..:I:::MMMMMMMMM...........
...............MMH::I...I:::..........III.I::MMMHMMMMMMM...........
..............MMMHMII.. ..............:MI:I.HIIIHM:HMMMM...........
.............:MMMMIM::...........:......:H..:II:MHIMMMMM...........
.............MMMMMMMMM......................I.MMMHHMMMMM:..........
............MMMMH:MMMMM........:.:.........:MMMMMMMMMMMMI..........
...........MMMMMMHMMMMMMM.. .............:MMMMMMMMMMMMMMM..........
........ .IMMMMMMMMMMMMMMMM............:MMMMMMMMMHMMMMMMM..........
..........MMMMMMMMMMMMMMMMMI:.......:IHMMMMMMMMM::MMMMMMM..........
.........MMMMMMMIMMMMMMMMMMH:::I:I:.::HMMMMMMMMMHMMMMMMMMI.........
........HMMMMMMM:MMMMMMMMMMI:::::::..:HMMMMMMMMIMMMMMMMMMM.........
.......IMMMMM..MI:MMMMMMMMM::::..:::::.MMMMMMMMMMMMMMMMMMM ........
......:MMMM....:MMHMMMMMM:::::.....::.:.MMMMMMMHMMMMMMMMMM.........
......MMI....:::IMMMMI:.:::::.....:I::::::HMMMHIM::::::MMMH........
.....MM.....:::IMIMMM:.......:....::::::::IMMHMM:I:::I:::MM .......
....MMM.....:I:.MIHMMM........:...:::::::HMMMMI:::::....::M:.......
...:MM:........:MMMHMM..................IMMMMM::...........M.......
...MMM........:::MMMMM......:..........:HMMMMM::...................
..:MM:.......:::::MMMM........... .. .::MMM:HM::.............:.....
..MMM........:::::MMMMM:I..HHIMHMHHHM :IMMHIMH::.............I.....
*/



/*

?$$  "$N        $$$  ^#$            $              d$*  "$d       '$$F  "$r   
'$$   $$k       9$$    '           d$N            $$F     *        $$>    *   
'$$   $$F       9$$  :             $$$r          $$$               $$>  f     
'$$   $$        9$$.e$            . #$$          $$$               $$L.$F     
'$$**#"         9$$ ^$            f  $$L         $$$               $$> #F     
'$$             9$$  '           .   '$$         $$$               $$>  F     
'$$             9$$     "        P""""$$N        '$$r     J        $$>    x   
{$$             9$$   .$              '$$         ^$$.   d$        $$r   dF   
""""           `""""""""       '""    """"           """"         """"""""    

.....               d*##$.                               
zP"""""$e.           $"    $o                              
4$       '$          $"      $                              
'$        '$        J$       $F                             
'b        $k       $>       $                              
$k        $r     J$       d$                              
'$         $     $"       $~                              
'$        "$   '$E       $                               
$         $L   $"      $F ...                           
$.       4B   $      $$$*"""*b                         
'$        $.  $$     $$      $F                        
"$       R$  $F     $"      $                         
$k      ?$ u*     dF      .$                         
^$.      $$"     z$      u$$$$e                      
#$b             $E.dW@e$"    ?$                     
#$           .o$$# d$$$$c    ?F                    
$      .d$$#" . zo$>   #$r .uF                    
$L .u$*"      $&$$$k   .$$d$$F                    
$$"            ""^"$$$P"$P9$                     
JP              .o$$$$u:$P $$                     
$          ..ue$"      ""  $"                     
d$          $F              $                      
$$     ....udE             4B                      
#$    """"` $r            @$                      
^$L        '$            $F                      
RN        4N           $                       
*$b                  d$                       
$$k                 $F                       
$$b                $F                       
$""               $F                       
'$                $                        
$L               $                        
'$               $                        
$               $                        
"   
*/


/*


Einstein
.+~                :xx++::
:`. -          .!!X!~"?!`~!~!. :-:.
{             .!!!H":.~ ::+!~~!!!~ `%X.
'             ~~!M!!>!!X?!!!!!!!!!!...!~.
{!:!MM!~:XM!!!!!!.:!..~ !.  `{
{: `   :~ .:{~!!M!XXHM!!!X!XXHtMMHHHX!  ~ ~
~~~~{' ~!!!:!!!!!XM!!M!!!XHMMMRMSXXX!!!!!!:  {`
`{  {::!!!!!X!X?M!!M!!XMMMMXXMMMM??!!!!!?!:~{
: '~~~{!!!XMMH!!XMXMXHHXXXXM!!!!MMMMSXXXX!!!!!!!~
:    ::`~!!!MMMMXXXtMMMMMMMMMMMHX!!!!!!HMMMMMX!!!!!: ~
'~:~!!!!!MMMMMMMMMMMMMMMMMMMMMMXXX!!!M??MMMM!!X!!i:
{~{!!!!!XMMMMMMMMMMMM8M8MMMMM8MMMMMXX!!!!!!!!X!?t?!:
~:~~!!!!?MMMMMM@M@RMRRR$@@MMRMRMMMMMMXSX!!!XMMMX{?X!
:XX {!!XHMMMM88MM88BR$M$$$$8@8RN88MMMMMMMMHXX?MMMMMX!!!
.:X! {XMSM8M@@$$$$$$$$$$$$$$$$$$$B8R$8MMMMMMMMMMMMMMMMX!X
:!?! !?XMMMMM8$$$$8$$$$$$$$$$$$$$BBR$$MMM@MMMMMMMMMMMMMM!!X
~{!!~ {!!XMMMB$$$$$$$$$$$$$$$$$$$$$$$$MMR$8MR$MMMMMMMMMMMMM!?!:
:~~~ !:X!XMM8$$$$$$$$$$$$$$$$$$$$$$$RR$$MMMMR8NMMMMMMMMMMMMM{!`-
~:{!:~`~':!:HMM8N$$$$$$$$$$$$$$$$$$$$$$$$$8MRMM8R$MRMMMMMMMMRMMMX!
!X!``~~   :~XM?SMM$B$$$$$$$$$$$$$$$$$$$$$$BR$$MMM$@R$M$MMMMMM$MMMMX?L
X~.      : `!!!MM#$RR$$$$$$$$$$$$$$$$$R$$$$$R$M$MMRRRM8MMMMMMM$$MMMM!?:
! ~ {~  !! !!~`` :!!MR$$$$$$$$$$RMM!?!??RR?#R8$M$MMMRM$RMMMM8MM$MMM!M!:>
: ' >!~ '!!  !   .!XMM8$$$$$@$$$R888HMM!!XXHWX$8$RM$MR5$8MMMMR$$@MMM!!!{ ~
!  ' !  ~!! :!:XXHXMMMR$$$$$$$$$$$$$$$$8$$$$8$$$MMR$M$$$MMMMMM$$$MMM!!!!
~{!!!  !!! !!HMMMMMMMM$$$$$$$$$$$$$$$$$$$$$$$$$$MMM$M$$MM8MMMR$$MMXX!!!!/:`
~!!!  !!! !XMMMMMMMMMMR$$$$$$$$$$$$R$RRR$$$$$$$MMMM$RM$MM8MM$$$M8MMMX!!!!:
!~ ~  !!~ XMMM%!!!XMMX?M$$$$$$$$B$MMSXXXH?MR$$8MMMM$$@$8$M$B$$$$B$MMMX!!!!
~!    !! 'XMM?~~!!!MMMX!M$$$$$$MRMMM?!%MMMH!R$MMMMMM$$$MM$8$$$$$$MR@M!!!!!
{>    !!  !Mf x@#"~!t?M~!$$$$$RMMM?Xb@!~`??MS$M@MMM@RMRMMM$$$$$$RMMMMM!!!!
!    '!~ {!!:!?M   !@!M{XM$$R5M$8MMM$! -XXXMMRMBMMM$RMMM@$R$BR$MMMMX??!X!!
!    '!  !!X!!!?::xH!HM:MM$RM8M$RHMMMX...XMMMMM$RMMRRMMMMMMM8MMMMMMMMX!!X!
!     ~  !!?:::!!!MXMR~!MMMRMM8MMMMMS!!M?XXMMMMM$$M$M$RMMMM8$RMMMMMMMM%X!!
~     ~  !~~X!!XHMMM?~ XM$MMMMRMMMMMM@MMMMMMMMMM$8@MMMMMMMMRMMMMM?!MMM%HX!
!!!!XSMMXXMM .MMMMMMMM$$$BB8MMM@MMMMMMMR$RMMMMMMMMMMMMMMMXX!?H!XX
XHXMMMMMMMM!.XMMMMMMMMMR$$$8M$$$$$M@88MMMMMMMMMMMMMMM!XMMMXX!!!XM
~   {!MMMMMMMMRM:XMMMMMMMMMM8R$$$$$$$$$$$$$$$NMMMMMMMM?!MM!M8MXX!!/t!M
'   ~HMMMMMMMMM~!MM8@8MMM!MM$$8$$$$$$$$$$$$$$8MMMMMMM!!XMMMM$8MR!MX!MM
'MMMMMMMMMM'MM$$$$$MMXMXM$$$$$$$$$$$$$$$$RMMMMMMM!!MMM$$$$MMMMM{!M
'MMMMMMMMM!'MM$$$$$RMMMMMM$$$$$$$$$$$$$$$MMM!MMMX!!MM$$$$$M$$M$M!M
!MMMMMM$M! !MR$$$RMM8$8MXM8$$$$$$$$$$$$NMMM!MMM!!!?MRR$$RXM$$MR!M
!M?XMM$$M.{ !MMMMMMSUSRMXM$8R$$$$$$$$$$#$MM!MMM!X!t8$M$MMMHMRMMX$
,-,   '!!!MM$RMSMX:.?!XMHRR$RM88$$$8M$$$$$R$$$$8MM!MMXMH!M$$RMMMMRNMMX!$
-'`    '!!!MMMMMMMMMM8$RMM8MBMRRMR8RMMM$$$$8$8$$$MMXMMMMM!MR$MM!M?MMMMMM$
'XX!MMMMMMM@RMM$MM@$$BM$$$M8MMMMR$$$$@$$$$MM!MMMMXX$MRM!XH!!??XMMM
`!!!M?MHMMM$RMMMR@$$$$MR@MMMM8MMMM$$$$$$$WMM!MMMM!M$RMM!!.MM!%M?~!
!!!!!!MMMMBMM$$RRMMMR8MMMMMRMMMMM8$$$$$$$MM?MMMM!f#RM~    `~!!!~!
~!!HX!!~!?MM?MMM??MM?MMMMMMMMMRMMMM$$$$$MMM!MMMM!!
'!!!MX!:`~~`~~!~~!!!!XM!!!?!?MMMM8$$$$$MMMMXMMM!!
!!~M@MX.. {!!X!!!!XHMHX!!``!XMMMB$MM$$B$M!MMM!!
!!!?MRMM!:!XHMHMMMMMMMM!  X!SMMX$$MM$$$RMXMMM~
!M!MMMM>!XMMMMMMMMXMM!!:!MM$MMMBRM$$$$8MMMM~
`?H!M$R>'MMMM?MMM!MM6!X!XM$$$MM$MM$$$$MX$f
`MXM$8X MMMMMMM!!MM!!!!XM$$$MM$MM$$$RX@"
~M?$MM !MMMMXM!!MM!!!XMMM$$$8$XM$$RM!`
!XMMM !MMMMXX!XM!!!HMMMM$$$$RH$$M!~
'M?MM `?MMXMM!XM!XMMMMM$$$$$RM$$#
`>MMk ~MMHM!XM!XMMM$$$$$$BRM$M"
~`?M. !M?MXM!X$$@M$$$$$$RMM#
`!M  !!MM!X8$$$RM$$$$MM#`
!% `~~~X8$$$$8M$$RR#`
!!x:xH$$$$$$$R$R*`
~!?MMMMRRRM@M#`       
`~???MMM?M"`
*/

/*

:';t)/!||||(//L+)'(-\\/ddjWWW#######WmKK(\!(/-|J=/\\t/!-/\!_L\) 
|-!/(!-)\L\)/!\5(!.!LWW###################WK/|!\\\\/!;\/\T\/((\ 
|!'//\//(-!t\Y/\L!m#####M####################WLt\\!)\/J-//)/;t\ 
--/-.\.\/\.!)///m######K#######################WK!/!-( )-!,|/\ 
//,\--`--!-/\(q#######DD##########################L\\\\-!!//!\\ 
-.-!\'!!\-\/:W########N############################W,).'-.-/\-' 
!.\!-!-!`!-!W#######P|+~**@@@#######################W/,/'\-/,\7 
--`,-- -/.:W###*P!'          \`Z8#####################;,\\`,\,\
`.'.'\`-.-d##5'-           -- '-:V@##########W#########_\-!-\\-
`, -,.'/,G##K- '               - )7KM###################\-----/
- '-  --:##@;                    -!ZZ###################W! \'!- 
'-.`- G###|.                    `,D8K###################|/-.-/ 
-' ,-//###@)                      -)ZWMW##################\` _\
- ' .:Yd###!                     `-!(K5K##################|(/L| 
- :\G###Z-                    ` ! -;55ZZ#################)(4) 
. -!W####!\                     `  ' !-tVG################XNVZ 
tt####@-.                        `  ')(W################D)8@ 
)8#####\                         .-`-/KW#################KD# 
||Z####W!-              .::,\.. -,;\bZKK######8#K#########(#8 
KN8#####( ,:!/GG_      d4KW8ZKW#WWK#W#88#######W##########WK# 
)/8K###K#W#WP~~~T4(    dW##7'___L#M####MM8W###W############bM8 
\!48#K####8##W*###WY;   WRob+~~######*ff/\NM8###############WW# 
.\\KW###W#,~t' !*~!',  -M@)    `~`,),' '.`K#################@KW 
.'8M###### -'..j/Z''    @//-  ,,\\+\'    :|W######M###########8 
:\#8#K###D              \!`             !:Z8###8@#####8W#W###8M 
q8W5######             `!-             `-)8##################M8 
8WZ8#M####-             /  .          .\tK############@######ZJ 
#W#@K###W#|              //           \\tW@###@K##W##W###K###Wm 
##8#M#8###P-            -=/,         /;D8W##############@###W## 
#8###M@####\-      ,   _)jJ;        -((WKK#####W####W##K######K 
###W@K##K##);     `\..KW##WK       )X)KW#M##W###MW##@#W######8# 
#K#W####@#@@/;-     ~M####M\    ,.\\=)D8W##W###W##########8W##@ 
####MW######(`\\'     PPK((.:|/!-\-/)8XN@WMK#######W##MK#@##### 
##8##MK#W#@#b!--\)L_. .(ZLWbW#\'- ,-N|/KM#######W###@########W# 
##KW###K#W###/-  !``~~Yff*N5f -' -.\))KK#######MK##W###M8W#W### 
#W###K@K######J--    .._dd/;)/- !//)NK#8W##########8########M#K 
##8W#K###W#####W!.   `YY\)\\)\7(-)4dW#8#@###K#W#######8######## 
M####8##K#KW###W#/,       '-\\//)88W#M#@#K##M###@##M#8##@#W#8#M 
ZW#W#M#K##########m       -)!/LtWW#W##@#W#####KW#######W###K### 
K##W#####W#M#8#####KL   .-//dD##8W#K######8##########MK###W##M# 
tN#W##W#W#M##########bb4dKW#@##W##K####MK####8###########W##### 
)NM#8W##@###@##############@##@##8##K#W####M##K##K#@###8##M#### 
(tMM###W##M8####@####@###@#########@####8W##8W################M 
tNZ##K###W####@#####8###/4N##8#W##W##M#8#MK#M8#K######W######## 
M/K@8###M@###M##########|!t*Z#N####8##M8Z@ZZ#M###@#W#####K###W# 
WVd4M######@############D,\`(+KKZD#8WK#5@84VZ#WM############W## 
K5WM8#8W#W########8######,,-!/))ZK5@K4)@+(/XV/Z###@###W###M#### 
+8WN@##@K##W###W#########b.-.\!||\X(5)Z/7\\\t5/K########W###### 
8M8###@###@##8#########KDbt! !.-!t`(-\\!.\/.\!ZdG###W#MW###G### 
~~~~~`~~~~~~~~~~~~~~~~'~` ''  ' ` ` ' '   `   ``~`~`~`~~~~'~~~~  

*/

/*

#
##
###
####
#####
#######
#######
########
########
#########
##########
############
##############
################
################
##############
##############                                              ####
##############                                           #####
##############                                      #######
##############                                 ###########
###############                              #############
################                           ##############
#################      #                  ################
##################     ##    #           #################
####################   ###   ##          #################
################  ########          #################
################  #######         ###################
#######################       #####################
#####################       ###################
############################################
###########################################
##########################################
########################################
########################################
######################################
######################################
##########################      #####
###  ###################           ##
##    ###############
#     ##  ##########
##    ###
###
##
#
*/


/*

LL             A
LL            A A
LL           AA AA
LL          AA   AA
LL          AAAAAAA
LL         AA     AA
LL         AA     AA
LLLLLLLLL  AA     AA
LLLLLLLLL  AA     AA
TTTTTTTTTT   OOOOOOO   UU     UU  RRRRRRR              EEEEEEEEE  IIIIIIIIII  FFFFFFFFF  FFFFFFFFF  EEEEEEEEE  LL
TTTTTTTT  OOOOOOOOO  UU     UU  RRRRRRRR             EEEEEEEEE  IIIIIIIIII  FFFFFFFFF  FFFFFFFFF  EEEEEEEEE  LL
TT      OO     OO  UU     UU  RR     RR            EE             II      FF         FF         EE         LL
TT      OO     OO  UU     UU  RR     RR            EE             II      FF         FF         EE         LL
TT      OO     OO  UU     UU  RRRRRRRR             EEEEEEEE       II      FFFFFFFF   FFFFFFFF   EEEEEEEE   LL
TT      OO     OO  UU     UU  RR  RR               EE             II      FF         FF         EE         LL
TT      OO     OO  UU     UU  RR   RR              EE             II      FF         FF         EE         LL
TT      OOOOOOOOO  UUUUUUUUU  RR    RR             EEEEEEEEE  IIIIIIIIII  FF         FF         EEEEEEEEE  LLLLLLLLL
TT       OOOOOOO    UUUUUUU   RR     RR            EEEEEEEEE  IIIIIIIIII  FF         FF         EEEEEEEEE  LLLLLLLLL
.
1
1
1
M
M
M
M
\M/
. ' M ` .
\##-#####-##/
\# ##### #/
###############
###############
\ ! ! ! ! ! /
)! ! ! ! !(
+---------+
+! ! ! ! !+
+----*----+
+`. .':`. .'+
+ .^. : .^. +
+:...:*:...:+
+`. .':`. .'+
+ .^. : .^. +
+:...:*:...:+
+`. .':`. .'+
+. ^. : .^ .+
+:....:*:....:+
+` .  ':`  . '+
+  .^. : .^.  +
+:....:*:....:+
+` .. ':` .. '+
+. '` .:. '` .+
+:....:*:....:+
+ `. .':`. .' +
+   X  :  X   +
+.'  `.:.'  `.+
+:......*......:+
+`.   .':`.   .'+
+   X   :   X   +
+ .' `. : .' `. +
+.......*.......+
+` . . ':` . . '+
+   X   :   X   +
+ '   ` : '   ` +
+../########....+
+`/#########\ .'+
+  ############   +
+ '############`  +
+:.......*.......:+
+ ` .  ' : `  . ' +
+    X   :   X    +
+ .'   `.:.'   `. +
+:.......*.......:+
+`      ':`      '+
+  `   '  :  `   '  +
+    X   : :   X    +
+  '   ` : : '   `  +
+:.......*.*.......:+
+`      ': :`      '+
+ `   '  : :  `   ' +
+   X   : X :   X   +
+  '   ` :' `: '   `  +
+:.......*...*.......:+
+`      ':` ':`      '+
+ `   '  : X :  `   ' +
+   X   :     :   X   +
+ '   ` :/   \: '   ` +
+:.......*.....*.......:+
+`      ':`   ':`      '+
+ `   '  : `.' :  `   ' +
+    X   :  ' `  :   X    +
+  '   ` :'     `: '   `  +
+:.......*.......*.......:+
+ `      ':`     ':`      ' +
+  ` . '  :  `.'  :  ` . '  +
+    ' `  :   ' `   :  ' `    +
+. '    ` : '     ` : '    ` .+
+..........*.........*..........+
+  ###########################  +
+  ###########################  +
+   ###########################   +
#########################################
###########################################
\   1   1   1   1   1   1   1   1   1   /
)  1   1   1   1   1   1   1   1   1  (
+-----:-----+-------------+-----:-----+
+     :     +             +     :     +
*------*-----*-------------*-----*------*
+XXXXXXXXXXX+XXXXXXXXXXXXXXX+XXXXXXXXXXX+
*-----*-----*---------------*-----*-----*
+ `.   :  . '+               +` .  :   .' +
+    . : '   +               +   ` : .    +
+    . *.    +                 +    .* .    +
+ . '  : `.  +                 +  .' :  ` . +
*:......*....:*                 *:....*......:*
+ `.   :   . '+                 +` .   :   .' +
+     `.:. '  +                   +  ` .:.'     +
+   . '* `.   +                   +   .' *` .   +
+ . '   :    `.+                   +.'    :   ` . +
*:.....*.......*                   *.......*.....:*
+  ` .. :  .. ' +                   + ` ..  : .. '  +
+     . *'     +                     +     `* .     +
+  .. ' :   ` . +                     + . '   : ` ..  +
*.:....*.......:*                     *:.......*....:.*
+   ` ..: . - '  +                     +  ` - . :.. '   +
+    .. * ..    +                       +    .. * ..    +
-------------------------------------------------------------------
1 +:       :      +:       :       :       :+      :       :+ 1
1+ :       :      +:       :       :       :+      :       : +1
###################################################################
1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
+---------------------------------------------------------------+
+! . ! . ! . ! . !+. ! . ! . ! . ! . ! . ! . ! .+! . ! . ! . ! . !+
+:!: :!: :!: :!: :!+ :!: :!: :!: :!: :!: :!: :!: +!: :!: :!: :!: :!:+
+.!.:.!.:.!.:.!.:.!+:.!.:.!.:.!.:.!.:.!.:.!.:.!.:+!.:.!.:.!.:.!.:.!.+
+XXXXXXXXXXXXXXXXXX+\     \  ..-#######-..  /     /+XXXXXXXXXXXXXXXXXX+
*-------------------* \    .-' \  1 1 1  / `-.    / *-------------------*
+  ` .    : ..  '  +   \.-' \   .-------.   / `-./   +  `  .. :    . '  +
+.......:.*:........+ .-' \  .-''         ``-.  / `-. +........:*.:.......+
+    .  '  : ` .    +\:  \  -'                 `-  /  :/+    . ' :  `  .    +
+..:.......:.....:..+/ \ .-'                     `-. / \+..:.....:.......:..+
+    ` .   :    .  ' + \.'                           `./ + `  .    :   . '    +
+.........:.*..:.....+  /                               \  +.....:..*.:.........+
+     .  '  :   ` .   + /                                 \ +   . '   :  `  .     +
+...:......:........:+ /                                   \ +:........:..........+
+    `  .  :  .  '    +/                                     \+    `  .  :  .  '    +
+...........*.........+                                         +.........*...........+
+     .  '  :   `  .   +                                         +   .  '   :  `  .     +
+...:.......:.........:+                                           +:.........:.......:...+
+    `  .    :   .   '  +                                           +  `   .   :    .  '    +
+..........:.*.:........+                                             +........:.*.:..........+
+     .   '  :   `  .    +                                             +    .  '   :  `   .     +
+...:.........:.........:+                                               +:.........:.........:...+
+   `   .     :     .   ' +                                               + `   .     :     .   '   +
+...........:.*..:........+                                                 +........:..*.:...........+
+      .   '  :   `  .     +                                                 +     .  '   :  `   .      +
+...:.........:..........:.+                                                   +.:..........:.........:...+
+     `  .     :      .  ' +                                                     + `  .      :     .  '     +
+            ` *  - '      +                                                       +      ` -  * '            +
-----------------------------------------------------------------------------------------------------------------
*/

/*


=   ==   => /                                                             
+# = #= +  $=>>  =                                                         
=+%>=$%=/#%+%>%+/ +>/+>+=                                                      
>=+$%#+#>%$#%##$=+$$/+$+=  >=                                                   
>>/%#%###########+#######>==+#>  /                                                
=%+//>$%#%#########################%%#/==              ==               /#$>           
+$+##+#########%##################$$%+/=              /%%%%%%###%###%%%%%%%           
==/+$#########=  =$#######>>#######$##>=                 #%>==##+ %##>>/%/             
//=/%#$#########                +######$%%++$+              ###++##/ +##++###>            
=>/+$############=                #########%%>=              ##$>>+$/ /$/>>##$             
/$##############%=             %######$#$+>=/+             ##$//### %##++##%             
=>>+%$###############%/>     =/$############$+%/=         ++++++++###+###++++###/          
=>/%%$$#########################################/          =/>>%>###+/#$>>>>>%%>>=          
==>+%#######################################$%/>=            $# %##  $##  >>=##>           
=>+##$$######################################++>=           $### +##  >#+ >## %##>          
/+++$#####################################$%$%/+>          $$+  =###########= %+           
>>>++####################################+>/+%=                                           
>>%#####################################$%/=                                            
>$##################################/+>/==>                                            
/#%/>################################+>//                       =>///>                  
=   %+$%##$######################$$//+%%>>                   +##$$#%%###$=              
= >$#/$$#####################$+=                       $#$=  >#    >##$             
>>/+=##############%/+#+$##%+>                     =##=    ##      ##+            
+%%###%%##%%%#% > +//= //%                     ##>    +#%      ###            
>  +>=+>+=%>=##$=> = =                          ##=   %##       ###            
=   =   #>//                               ###>/##%       $##=            
>//=                =$                                    #####>      /###=             
/%+             =%     >/+++/>                          =>     >+###$>               
=$%          >%  +###$+>====>=                              ++/>                   
/#>       >%/##$>                                                                
=#+     >###/                                                                   
=#%   >#%=                                           ++>   /%/                 
=#+  #                                        >=====###>==$##>==+$/           
%#>+/                                        %%%%%%###%%%###%%%%%%=          
###                                          >%%%%###%%%###%###=            
/#%                                           ==>##==##$=/##===>            
#/                                        /$$$$$##$$###$###$$###/          
/+    //=                                      =##  ##% >##                
>%  %+                                      $$$$##$$###$###$###            
# #+                                      >>>>=====##$=====>$$>           
$+#                                       /%%%%%%%%###%%%%%%%%+           
#%                                                ##+                    
>$                                                ##>                    
#                                                                       
/+                                                                      
#                                                                      
$                                                                      
%                                                                      
=   

*/

/*

iEid
iDDDDDDDd
iDDDDDDDDDD
EDDi         iDLINUSTDISSB
DDDDDDi    iDDDDDDDE DDDDD
DDiDDDDDDiDDDDDDDE   DDDDD
DD  EDDDDDDDDDDD     DDDDD
DD   iDDDDDDDDE      DDDDD
DD iDDDDDiDDDDDDi    DDDDD
DDDDDDE   iDDDDDDDiE DDDDD
dDDDE        iFUCKAPPLEDDD
iDDDDDDDDDD
iDDDDDDD
iDid

ๅซไบบ่ฆๅซ็จ‹ๅบๅ‘˜,ๅ‘†่Œๅ•็บฏๅฏ็ˆฑๅคš!

*/


/*
่ฏทไป”็ป†็œ‹ๆœ€ๅŽไธ€่กŒ็š„ๆŸไบ›่‹ฑๆ–‡ๅญ—ๆฏใ€‚


LEEIIO01       CHAOS0      MADE!    00000000             00001    10000    0000
000 1001     000  000      000     0  001 0              000      00001  0000
000  000     000  000      000        00                 001      10000  0000
000  000     000  100      000        00                 000      10 0000 100
000  000     000  000      000        001                000      10 1001 100
000  00      100  001      000        001       001      000      00  00  000
F000100        U00001      C0001      K0001      000     G0001    F001     W00!



*/

/*


ใ€€โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†ใ€€
ใ€€ใ€€โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€ใ€€โ—†โ—†ใ€€ใ€€ใ€€ใ€€  โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€ใ€€โ—†โ—†โ—†ใ€€โ—†โ—†โ—†ใ€€ใ€€โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€โ—†โ—†โ—†ใ€€ใ€€โ—†โ—†โ—†โ—†ใ€€ โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†โ—†โ—†โ—†ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†โ—†โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†โ—†โ—†ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†โ—†ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†ใ€€  โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€โ—†โ—†โ—†ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€โ—†โ—†โ—†ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€โ—†โ—†โ—†ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€โ—†โ—†โ—†ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€โ—†โ—†โ—†ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€โ—†โ—†โ—†ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†โ—†ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ—†โ—†โ—†ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*/
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//    ...๏ผŽ๏ผŽโˆต โˆดโ˜…๏ผŽโˆดโˆตโˆด โ•ญ โ•ฏโ•ญ โ•ฏโ•ญ โ•ฏโ•ญ โ•ฏโˆดโˆตโˆดโˆตโˆด 
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//    ๏ผŽโ˜†๏ผŽโˆตโˆดโˆต๏ผŽโˆดโˆตโˆดโ–โ– โ–โ– โ–โ– โ–โ–โ˜† โ˜…โˆตโˆด 
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//    โ–๏ผŽโˆดโˆตโˆดโˆต๏ผŽโˆดโ–…โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ˜† โ˜…โˆต 
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//    โ—ฅโ–ˆโ–…โ–…โ–…โ–…โ–ˆโ–ˆโ–ˆโ–…โ–ˆโ–…โ–ˆโ–…โ–ˆโ–…โ–ˆโ–…โ–ˆโ–…โ–ˆโ–ˆโ–ˆโ—ค 
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//    ๏ผŽ โ—ฅโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ—ค ๆˆ‘ไปฌ็š„ๅพ้€”ๆ˜ฏๆ˜Ÿ่พฐๅคงๆตท
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//    .๏ผŽ.๏ผŽโ—ฅโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ– โ—ค
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//                                 _(\_/) 
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//                               ,((((^`\
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//                               ((((  (6 \ 
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//                            ,((((( ,    \
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//         ,,,_              ,(((((  /"._  ,`,
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//        ((((\\ ,...       ,((((   /    `-.-'
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//        )))  ;'    `"'"'""((((   (ๆˆ‘ๆ˜ฏไปฃ้ฉฌ      
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//      (((  /            (((      \
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//        )) |                      |
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//       ((  |        .       '     |
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//       ))  \     _ '      `t   ,.')
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//       (   |   y;- -,-""'"-.\   \/  
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//      )   / ./  ) /         `\  \
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//          |./   ( (           / /'
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//          ||     \\          //'|
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//          ||      \\       _//'||
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//          ||       ))     |_/  ||
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//          \_\     |_/          ||
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//          `'"                  \_\
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//   โ•ญโ”˜โ””โ”˜โ””โ•ฎ
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  โ””โ”๏ผŽ๏ผŽโ”Œโ”˜โ”€โ”€โ”€โ”€โ•ฎ
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  โ•ญโ”ดโ”€โ”€โ”ค          โ”œโ•ฎ
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  โ”‚๏ฝใ€€๏ฝโ”‚          โ”‚ โ—
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  โ•ฐโ”€โ”ฌโ”€โ•ฏ          โ”‚
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//      ไปฃ็ ๅฐฑๆ˜ฏ็‰› 
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€/////////////////////////////////////////////////////////////////////////////
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€// โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€// โ”‚โ–‰โ–‰โ–‰โ–‰โ–‰โ–‰โ–‰โ–‰โ–‰โ–‰โ–‰ใ€€ 99.9%โ”‚
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€// โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//   ๅผ€ๅ‘่ฟ›ๅบฆ
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€/////////////////////////////////////////////////////////////////////////////
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//              โ—ขโ—คโ—ขโ—ค
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  ใ€€ใ€€ใ€€ใ€€ใ€€โ—ขโ–ˆโ–ˆโ–ˆโ–ˆโ—ค
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  ใ€€ใ€€ใ€€โŠ™โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ—ค
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  ใ€€โ—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ—ค         ้ฝๅฟƒๅๅŠ›
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  ใ€€ใ€€โ–ผใ€€ใ€€๏ฝžโ—ฅโ–ˆโ–ˆโ–ˆโ—ค
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  ใ€€ใ€€โ–ฒโ–ƒโ–ƒโ—ขโ–ˆโ–ˆโ–ˆใ€€โ—ใ€€ใ€€โ—ใ€€ใ€€โ—ใ€€ใ€€โ—ใ€€ใ€€โ—ใ€€ใ€€โ—ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ–ˆโ–ˆโ–ˆ๏ผโ–ˆใ€€๏ผโ–ˆใ€€๏ผโ–ˆใ€€๏ผโ–ˆใ€€๏ผโ–ˆใ€€๏ผโ–ˆใ€€ใ€€ใ€€โ—ขโ—ค
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ—ค
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  ๏ผƒใ€“โ—‹ใ€“ใ€“ใ€“ใ€“ใ€“โ—‹ใ€“ใ€“ใ€“ใ€“ใ€“ใ€“โ—‹ใ€“ใ€“ใ€“ใ€“ใ€“โ—‹ใ€“๏ผƒ 
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  ใ€€ใ€€โ†“ใ€€ใ€€ใ€€ใ€€ใ€€โ†“ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ†“ใ€€ใ€€ใ€€ใ€€ใ€€โ†“ 
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  ใ€€โ˜†โ˜…โ˜†ใ€€ใ€€ใ€€โ˜†โ˜…โ˜†ใ€€ใ€€ใ€€ใ€€โ˜†โ˜…โ˜†ใ€€ใ€€ใ€€โ˜†โ˜…โ˜† 
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  โ˜†ใ€€็ฅžใ€€โ˜†ใ€€โ˜†ใ€€ๆฅใ€€โ˜†ใ€€ใ€€โ˜†ใ€€ไน‹ใ€€โ˜†ใ€€โ˜†ใ€€็ฌ”ใ€€โ˜† 
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  ใ€€โ˜†โ˜…โ˜†ใ€€ใ€€ใ€€โ˜†โ˜…โ˜†ใ€€ใ€€ใ€€ใ€€โ˜†โ˜…โ˜†ใ€€ใ€€ใ€€โ˜†โ˜…โ˜† 
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  ใ€€ใ€€โ†“ใ€€ใ€€ใ€€ใ€€ใ€€โ†“ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ†“ใ€€ใ€€ใ€€ใ€€ใ€€โ†“ 
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€//  ใ€€ใ€€โ€ปใ€€ใ€€ใ€€ใ€€ใ€€โ€ปใ€€ใ€€ใ€€ใ€€ใ€€ใ€€โ€ปใ€€ใ€€ใ€€ใ€€ใ€€โ€ป 
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€/**
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€* http://www.freebuf.com/
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*           _.._        ,------------.
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*        ,'      `.    ( We want you! )
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*       /  __) __` \    `-,----------'
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*      (  (`-`(-')  ) _.-'
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*      /)  \  = /  (
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*     /'    |--' .  \
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*    (  ,---|  `-.)__`
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*     )(  `-.,--'   _`-.
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*    '/,'          (  Uu",
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*     (_       ,    `/,-' )
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*     `.__,  : `-'/  /`--'
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*       |     `--'  |
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*       `   `-._   /
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*        \        (
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*        /\ .      \.  freebuf
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*       / |` \     ,-\
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*      /  \| .)   /   \
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*     ( ,'|\    ,'     :
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*     | \,`.`--"/      }
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*     `,'    \  |,'    /
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*    / "-._   `-/      |
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*    "-.   "-.,'|     ;
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*   /        _/["---'""]
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*  :        /  |"-     '
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*  '           |      /
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*              `      |
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*/
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€/** 
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€* https://campus.alibaba.com/
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*                                 `:::::::::::,
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*                             `::;:::::::;:::::::,  `
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*                          `::;;:::::::@@@@;:::::::`
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*                        ,:::::::::::::@    #@':::::`
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*                      :::::::::::::::'@@      @;::::
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*                    ::::::::::::'@@@@'```      .+:::`
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*                  ::::::::::;@@@#.              ,:::,
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*                .::::::::+@#@`                   ::::
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*               :::::::+@@'                       ::::
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*             `:::::'@@:                         `:::.
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*            ,::::@@:  `                         ::::
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*           ;::::::@                            .:::;
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*          :;:::::;@`        `                  :::;
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*         :::::::::@`        @                 ;::::
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*        :::::::::#`          @`              ,::::
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*       :::::::::@`         +@ @             .::::`
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*      .::::::'@@`       `@@'  @             ::::,
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*      :::::::++@@@@@@@@@@.                 ::::;
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*     ;:::::::+,   `..`                    :::::
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*    ,::::::::',                          :::::
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*    :::::::::+,                         :::::`
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*   :::::::::+@.                        ,::::.`                     `,
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*   ::::::;;@+                         .::;::                     `;
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*  :::::::@@                          `:::;:                   `::``
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*  ::::::#@                           ;::::                  .::`
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*  :::::;@                           :::::`               .;::`
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*  :::::@                           `:;:::            `::::;
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*  :::::#                           :::::.        `,;:::::
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*  ::::::                    `      ::::::,.,::::::::::.
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*  ,::::::`              .::        ::::::::::::::::;`
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*   ;::::::::,````.,:::::,          ::::::::::::::.
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*    :::::::::::::::::: `           `::::::::::`
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*     `::::::::::::,                  .:::.
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*         `..`
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€*/
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€```
ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€ใ€€

About

๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅๅพฎไฟกๅ…ฌไผ—ๅท: XLsnow๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ=> Cydiaๆ’ไปถ Logos่ฏญ่จ€ ๅผ€ๅ‘Tweak.xm Cydia Substrate ๆณจๅ…ฅdylib iOS้€†ๅ‘ๅทฅ็จ‹ๅผ€ๅ‘ ่ถŠ็‹ฑJailbreak debๆ’ไปถ - fishhook / Frida / iOSOpenDev / Cycript / MachOView / IDA / Hopper Disassembler / MonkeyDev / Class-dump / Theos / Reveal / Dumpdecryptd / FLEX / ๆฑ‡็ผ–Assembly / CaptainHook / lldb/LLVM/XNU/Darwin/iOS Reverse

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Logos 64.4%
  • POV-Ray SDL 20.4%
  • C++ 12.6%
  • Swift 0.8%
  • M4 0.3%
  • Assembly 0.3%
  • Other 1.2%