【脱獄アプリ開発】第9回SyslogをON/OFFできるFlipSwitchトグルの作成方法
Jailbreak Tweakを開発するときなどにデバイスの情報をログとして出力する「syslogd to var/log/syslog」があります。
過去にSBSettingsのトグルとしてもありましたが、今回はそれと同様の動作をするFlipSwitchトグルの作成方法を紹介します。
Contents
syslogd to var/log/syslogの使い方
名前の通り/var/log/syslogにログファイルをリアルタイムで生成します。OpenSSHとBigBoss Recommended Toolsをインストールしていれば、MacのターミナルなどからSSHでiPhoneに接続しリアルタイムでログを確認できます。
#SSHでiPhoneに接続Tweak作成時などで上手いこと行かない場合、ソースファイルにNSLog()を記述して調べてみると解決の糸口に繋がるかと思います。
ssh [email protected]
#tailコマンドでログを確認
tail -f /var/log/syslog
#NSLogなどで一部の名称のみ確認したい場合(例.hoge)
tail -f /var/log/syslog | grep hoge
TheosにFlipSwitchのテンプレートを入れる
Link:https://github.com/a3tweaks/FlipswitchNIC Templateの中にある「iphone_flipswitch_switch.nic.tar」を、Macの"/opt/theos/templates/iphone"ディレクトリに入れます。そうすると、Theosのパッケージを作成する項目にFlipSwitchが追加されます。
Theosの構築などについては過去記事を参照ください。
【脱獄アプリ開発】第7回theosのインストールから簡単なTweakの作成までのガイドライン | Will feel Tips
【脱獄アプリ開発】第8回armv6からarm64(iPhone 3Gから5s)に対応したTweakの作成 | Will feel Tips
Syslog Toggleに必要な動作
1.syslogdのデーモンをON/OFFするlaunchctlコマンドで"/System/Library/LaunchDaemons/com.apple.syslogd.plist"をunload/loadしてあげることで可能となります。
ただし、FlipSwitchではSBSettingsのようにroot権限で動作することが出来ないため、Theosでいう"tool"を使ったバイナリを別に作成します。以下は、main.mmに記述していきます。
#import <Foundation/NSTask.h>このようにNSTaskを利用して実行することが出来ます。
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath: @"/bin/launchctl"];
//unload
NSArray *unload = [NSArray arrayWithObjects: @"unload", @"/System/Library/LaunchDaemons/com.apple.syslogd.plist", nil];
[task setArguments:unload];
[task launch];
//load
NSArray *load = [NSArray arrayWithObjects: @"load", @"/System/Library/LaunchDaemons/com.apple.syslogd.plist", nil];
[task setArguments:load];
[task launch];
2."/etc/syslog.conf"ファイルを編集する
/var/log/syslogに出力するONの時は、"*.* /var/log/syslog"
OFFの時は、"#*.* /var/log/syslog"先頭をコメントアウトしています。
static BOOL syslogEnabled;hasPrefix:@"*.* /var/log/syslog"で先頭の文字に#がない場合、syslogEnabledの値がYESになります。
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];
NSData *data = [fileHandle readDataToEndOfFile];
NSString *str = [[NSString alloc]initWithData:data
encoding:NSUTF8StringEncoding];
syslogEnabled = [str hasPrefix:@"*.* /var/log/syslog"];
[fileHandle closeFile];
これを利用してファイルを編集します。
static NSString *filePath = @"/etc/syslog.conf";以上のような方法でバイナリを作成します。
//OFFにするときの文字列
NSString *str1 = @"#*.* /var/log/syslog\n";
//ONにするときの文字列
NSString *str2 = @"*.* /var/log/syslog\n";
NSFileManager *manager = [NSFileManager defaultManager];
//一度"/etc/syslog.conf"を削除
if ([manager removeItemAtPath:filePath error:nil]) {
//syslog.confを新規作成
[manager createFileAtPath:filePath contents:nil attributes:nil];
if (syslogEnabled) {
//syslogがONの時OFFにする
[str1 writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
[task setArguments:unload];
[task launch];
[task setArguments:load];
[task launch];
} else {
//OFFの時ONにする
[str2 writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
[task setArguments:load];
[task launch];
}
}
通常toolで作成した場合、"/usr/bin"ディレクトリに入りますが、FlipSwitchのバンドルに入れて見た目をスッキリさせます。名前を「syslogsw」としてFlipSwitch側を「SyslogToggle.bundle」とします。
TOOL_NAME = syslogswこうすると「SyslogToggle.bundle」の中に「syslogsw」が入ります。
syslogsw_FILES = main.mm
syslogsw_INSTALL_PATH = /Library/Switches/SyslogToggle.bundle
また、root権限で実行させるようにするためパーミッションを「4755」にします。
before-package::これでdebパッケージにする前にパーミッションを変更します。
sudo chmod 4755 $(THEOS_STAGING_DIR)/Library/Switches/SyslogToggle.bundle/syslogsw
3.FlipSwitchでのON/OFF
ソースはSwitch.xファイルを見てコンパイルしますが、Xcodeで編集した場合にシンタックスハイライトされないためシンボリックリンクを作って編集すると見やすくなります。
mv Switch.x Switch.mm; ln -s Switch.mm Switch.x
#import <Foundation/Foundation.h>メインは、"syslogsw"を実行させることになります。
#import <UIKit/UIKit.h>
#import "FSSwitchDataSource.h"
#import "FSSwitchPanel.h"
static NSString *logPath = @"/var/log/syslog";
static NSString *filePath = @"/etc/syslog.conf";
static BOOL syslogEnabled;
@interface SyslogToggleSwitch : NSObject <FSSwitchDataSource>
@end
@implementation SyslogToggleSwitch
- (id)init
{
if ((self = [super init])) {
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];
NSData *data = [fileHandle readDataToEndOfFile];
NSString *str = [[NSString alloc]initWithData:data
encoding:NSUTF8StringEncoding];
syslogEnabled = [str hasPrefix:@"*.* /var/log/syslog"];
[fileHandle closeFile];
}
return self;
}
- (FSSwitchState)stateForSwitchIdentifier:(NSString *)switchIdentifier
{
return syslogEnabled;
}
- (void)applyState:(FSSwitchState)newState forSwitchIdentifier:(NSString *)switchIdentifier
{
if (newState == FSSwitchStateIndeterminate)
return;
syslogEnabled = newState;
system("/Library/Switches/SyslogToggle.bundle/syslogsw");
}
4.スイッチ長押し時にログファイルサイズを表示/削除させる
//スイッチ長押しで実行する処理
- (void)applyAlternateActionForSwitchIdentifier:(NSString *)switchIdentifier
{
//syslog(logPath)のファイルサイズを取得
NSFileManager *fm = [NSFileManager defaultManager];
NSDictionary *attribute = [fm attributesOfItemAtPath:logPath error:nil];
NSNumber *fileSize = [attribute objectForKey:NSFileSize];
float num = [fileSize floatValue];
//KBに変換
num /= 1028;
//floatをNSStringに変換し、@"%.0f KB",roundf(num)で小数点を消し四捨五入
NSString *logSize = [[NSString alloc] initWithFormat:@"%.0f KB",roundf(num)];
//アラートを表示させる
UIAlertView *alert =
[[UIAlertView alloc] initWithTitle:@"Logfile Size\nLocation: /var/log/syslog"
message:logSize
delegate:self
cancelButtonTitle:@"Dismiss"
otherButtonTitles:@"Clear File",nil];
[alert show];
[alert release];
}
-(void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) {//Dismiss
} else if (buttonIndex == 1) {//Clear Fileを押した時
///var/mobile以下はFlipSwitchからアクセス出来るので空ファイルを作成
system("touch /var/mobile/Library/Caches/syslogclear");
//syslogを削除した場合、再度ONにする必要があるためOFFにする
system("/Library/Switches/SyslogToggle.bundle/syslogsw");
syslogEnabled = NO;
}
}
@end
static NSString *clearCache = @"/var/mobile/Library/Caches/syslogclear";5.初回起動時に動作しない問題を修正
static NSString *logPath = @"/var/log/syslog";
//syslogclearファイルが合った場合、OFFにする記述を追加
NSString *str1 = @"#*.* /var/log/syslog\n";
NSFileManager *manager = [NSFileManager defaultManager];
if ([manager removeItemAtPath:clearCache error:nil]) {
//syslog削除
[manager removeItemAtPath:logPath error:nil];
//syslogをOFFにする
[str1 writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
[task setArguments:unload];
[task launch];
[task setArguments:load];
[task launch];
}
#!/bin/shインストール後に一度"syslogsw"を実行することで回避します。
/Library/Switches/SyslogToggle.bundle/syslogsw
exit 0
まとめ
ずらずらとコードを書きましたが、断片的で分かりにくいかと思います。GitHubにソースを上げておいたので参考にしてください。Link:https://github.com/ichitaso/Syslog-Toggle-Flipswitch
ichitasoリポにも「Syslog Toggle(Flipswitch)」という名前で入れておきました。Cydiaの設定がHacker以上で表示されるようになっています。
昨夜はWWDC 2014でiOS 8や新しい言語「Swift」が発表されましたね!脱獄関連の動きも気になるところですが、とりあえず今できることをやろうということで紹介しました。
それでは!!