่ถ็ฑๅผๅๅธธ่ง็ๅทฅๅ ทOpenSSH๏ผDumpdecrypted๏ผclass-dumpใTheosใRevealใIDA๏ผHopper๏ผ
https://xlsn0w.github.io/CydiaRepo
https://xlsn0w.github.io/ipas
// _0_
// _oo0oo_
// o8888888o
// 88" . "88
// (| -_- |)
// 0\ = /0
// ___/`---'\___
// .' \\| |// '.
// / \\||| : |||// \
// / _||||| -:- |||||- \
// | | \\\ - /// | |
// | \_| ''\---/'' |_/ |
// \ .-\__ '-' ___/-. /
// ___'. .' /--.--\ `. .'___
// ."" '< `.___\_<|>_/___.' >' "".
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
// \ \ `_. \_ __\ /__ _/ .-` / /
// XL---`-.____`.___ \_____/___.-`___.-'---sn0w
// `=---='
ๆธ ๅ:
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้กน็ฎ่ฏๅซ่ฏญ่จ
( 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/ไธๅณๅฏ
/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:
...
** ๅฝ็ถไฝ ไนๅฏไปฅ็ดๆฅ 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
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 #้ ็ฝฎๅ
ๅ ถไธญๅ ๆฌ๏ผ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ๆฏไธไธชๅผๆบ็็ๅบ,้ขๅๅ้ข็ผ็จ,ๅฎ่ฝๅ ่ฎธไฝ ๅจๆฏไธไธช็ฑปๅๆฏไธไธชๅฎไพไธญๅญๅจ็ๆนๆณ้้ขๅ ๅ ฅไปปไฝไปฃ็ ใๅฏไปฅๅจๆนๆณๆง่กไนๅๆ่ ไนๅๆง่ก,ไนๅฏไปฅๆฟๆขๆๅๆ็ๆนๆณใ้่ฟ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);
}
}
}
} ไธ่ฟฐไปฃ็ ไธป่ฆๅไปฅไธๅ ไปถไบ:
- ่ทๅๅๆฅ็ฑป็ๆนๆณ็IMPๆฏไธๆฏๆๅไบ_objc_msgForward,ๅฆๆๆฏๅฐฑๆ่ฏฅๆนๆณ็IMPๅๆๅๅป
- ๅฆๆๆฏๅ ็ฑปๅฐฑๅ ้คswizzledClasses้้ข็ๆฐๆฎ
- ๆๆฐๅปบ็ฑป็isaๆ้ๆๅๅๆฅ็ฑป, ๅ ถๅฎๅฐฑๆฏๆhook็ๆถๅๅ็ๅค็,ๅ่ฟๅไบ
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
็จ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
https://www.macports.org/install.php
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 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).
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]));
}
}
Calling real open('/var/mobile/Applications/161DA598-5B83-41F5-8A44-675491AF6A2C/Test.app/Test', 0)
Mach-O Magic Number: feedface
Calling real close(3)
...
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 section
s 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 nlist
s (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:
ๆบ็ ๅฐๅ๏ผ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 ๏ผๅฏ้ๅฎๅๆไปถ็ฑปๅ
็ฎๅๆฅ่ฏด๏ผๅฐฑๆฏไธไธช็ฑไธๅ็็ผ่ฏๆถๆๅ็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ๆไปถ
่ฟไธชๅทฅๅ ทๆฏ้่ฟๅฝไปค่กๅทฅๅ ท่ฎฟ้ฎ่นๆๆๆบ๏ผๆง่กๅฝไปค่ก่ๆฌใๅจCydiaไธญๆ็ดขopenssh๏ผๅฎ่ฃ ใๅ ทไฝ็จๆณๅฆไธ๏ผ 1ใๆๅผmacไธ็terminal๏ผ่พๅ ฅๅฝไปคssh [email protected]๏ผ่ถ็ฑ่ฎพๅคipๅฐๅ๏ผ 2ใๆฅไธๆฅไผๆ็คบ่พๅ ฅ่ถ ็บง็ฎก็ๅ่ดฆๅทๅฏ็ ๏ผ้ป่ฎคๆฏalpine 3ใๅ่ฝฆ็กฎ่ฎค๏ผๅณๅฏroot็ปๅฝ่ฎพๅค ไฝ ไนๅฏไปฅๅฐไฝ mac็ๅ ฌ้ฅๅฏผๅ ฅ่ฎพๅค็/var/root/.ssh/authorized_keysๆไปถ๏ผ่ฟๆ ทๅฐฑๅฏไปฅๅ ๅฏ็ปๅฝrootไบใ
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ๆฏ็ฑ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ๅฐฑๆฏ่ๅ็็ ธๅฃณๅทฅๅ ท๏ผๆ่ฐ็ ธๅฃณ๏ผๅฐฑๆฏๅฏน 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
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ๆฏๅคงๅ้ผ้ผ็ๅ็ผ่ฏๅทฅๅ ท๏ผๅฎไน้ๅๅทฅ็จไธญๆ่ด็ๅ็็ฅๅจไนไธใๆฏๆWindowsใLinuxๅMac OS X็ๅคๅนณๅฐๅๆฑ็ผๅจ/่ฐ่ฏๅจ๏ผๅฎ็ๅ่ฝ้ๅธธๅผบๅคงใclass-dumpๅฏไปฅๅธฎๆไปฌ็ฝๅๅบ่ฆๅๆ็ๅคดๆไปถ๏ผIDA่ฝๅคๆทฑๅ ฅๅไธชๅฝๆฐ็ๅ ทไฝๅฎ็ฐ๏ผๆ ่ฎบ็C๏ผC++๏ผOC็ๅฝๆฐ้ฝๅฏไปฅๅ็ผ่ฏๅบๆฅใไธ่ฟๅ็ผ่ฏๅบๆฅ็ๆฏๆฑ็ผไปฃ็ ๏ผไฝ ้่ฆๆไธๅฎ็ๆฑ็ผๅบ็กๆ่ฝ่ฏป็ๆใ IDAๅพๅๆบๅจๆง่ฝ๏ผๆ็ๆบๅจ็ปๅธธๅกไฝไธๅจ๏ผ๏ผ่ฟๆๅฆๅคไธไธชๅ็ผ่ฏๅทฅๅ ทHopper๏ผๅฏนๆบๅจๆง่ฝ่ฆๆฑๆฒก้ฃไน้ซ๏ผไนๅพๅฅฝ็จ๏ผๆไบบ่ถ่ดง็ๅฉๅจใ
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่ฟๆฅ็้ฆ้ๆนๆก
ไปฅไธ้ฝๆฏ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
ๅฎ็ฝ๏ผ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 ๆไปถใ ๅฆไธๅพ
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/
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):
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ๅ ไฝฟ็จ ใ
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/
ไธป้กต๏ผ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
็จ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ๅช่ฝ็ ธ็ธๅบๆๆบๅค็ๅจๅฏนๅบ็ๅฃณใ
- http://bbs.iosre.com/t/dumpdecrypted-app/22/65
- http://bbs.iosre.com/t/dumpdecrypted-app/160
- http://bbs.iosre.com/t/class-dump-error-cannot-find-offset-for-address-xxxx-in-dataoffsetforaddress/1911
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.
- _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ไผๅจโๅฏ็ ้่ฏฏโ็่ญฆๅๆกๅผนๅบๆถๅไธ๏ผๅทฆไพงไผๆพ็คบๅบ่ฟๆ ท็่ฐ็จๆ ไธๅผ ๅพ็ๅฎๆฏไปๅฎ็็ปๅฝ่ฟ็จ
- http://c.blog.sina.com.cn/profile.php?blogid=cb8a22ea89000gtw
่ฟ็ฏๆ็น่ฟๆถไบ๏ผไฟฎๆนlibReveal.plistๆถ็ปๅธธๅบ็ฐ็ฝ่นๆ๏ผๅฏไปฅๅผบๅถ่ฟๅ ฅๅฎๅ จๆจกๅผๅๅฐๆไปถไฟฎๆนๅฅฝๅ้ๆฐๅฏๅจใ - http://hilen.github.io/2015/12/01/Reveal-Loader/
// _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/
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* `:::::::::::,
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* `::;:::::::;:::::::, `
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* `::;;:::::::@@@@;:::::::`
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* ,:::::::::::::@ #@':::::`
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* :::::::::::::::'@@ @;::::
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* ::::::::::::'@@@@'``` .+:::`
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* ::::::::::;@@@#. ,:::,
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* .::::::::+@#@` ::::
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* :::::::+@@' ::::
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* `:::::'@@: `:::.
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* ,::::@@: ` ::::
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* ;::::::@ .:::;
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* :;:::::;@` ` :::;
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* :::::::::@` @ ;::::
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* :::::::::#` @` ,::::
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* :::::::::@` +@ @ .::::`
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* .::::::'@@` `@@' @ ::::,
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* :::::::++@@@@@@@@@@. ::::;
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* ;:::::::+, `..` :::::
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* ,::::::::', :::::
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* :::::::::+, :::::`
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* :::::::::+@. ,::::.` `,
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* ::::::;;@+ .::;:: `;
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* :::::::@@ `:::;: `::``
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* ::::::#@ ;:::: .::`
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* :::::;@ :::::` .;::`
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* :::::@ `:;::: `::::;
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* :::::# :::::. `,;:::::
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* :::::: ` ::::::,.,::::::::::.
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* ,::::::` .:: ::::::::::::::::;`
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* ;::::::::,````.,:::::, ::::::::::::::.
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* :::::::::::::::::: ` `::::::::::`
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* `::::::::::::, .:::.
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ* `..`
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ*/
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ```
ใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใใ