关于如何拓展守护进程的示例中遇到的问题。

Run a daemon (as root) on iOS 继续讨论:

snakeninny
snakeninny14-05-11
Originality: http://bbs.iosre.com/forum.php?mod=viewthread&tid=204&page=1&extra=#pid10961
Author: snakeninny
Please include the above name and link with repost, thank you.

Hello people!
A lot of you have been asking about the writing of a daemon on iOS recently, and Chris Alvares’ tutorial seems to be a little bit outdated. So today I’m gonna present you a simple guide of writing a daemon (and run it as root) on iOS, and this post will not only cover the process of composing a daemon, but the very basic theory contained in it. Our target today is a working daemon that reboots iOS when it receives a specified notification, “com.iosre.rootdaemon.reboot”. Have fun!

Part I Basic theory

  1. Daemon
    What’s a daemon? According to wikipedia, a daemon “is a computer program that runs as a background process, rather than being under the direct control of an interactive user. Traditionally daemon names end with the letter d: for example, syslogd is the daemon that implements the system logging facility and sshd is a daemon that services incoming SSH connections.” You can name a few other daemons on iOS, say backboardd, mediaserverd, apsd, etc etc. Daemons are started by the first process on iOS, launchd, which is also a daemon, on boot time. What can a daemon do? It “serves the function of responding to network requests, hardware activity, or other programs by performing some task”. Note, daemons (running as root) can be soooooo powerful while staying low that even powerusers may not know the existence of a daemon, so some malwares are born as daemons. This post is for educational purposes only, you take the charge if you’re doing something risky.

Daemon ownership
Daemons are launched by launchd, via “launchctl” command plus their configuration files. On its man page, we should pay special attention to this sentence:“Note that per-user configuration files (LaunchAgents) must be owned by the user loading them. All system-wide daemons (LaunchDaemons) must be owned by root. Configuration files must not be group- or world-writable. These restrictions are in place for security reasons, as allowing writability to a launchd configuration file allows one to specify which executable will be launched.” Because daemons are loaded by launchd, which is owned by root:wheel,
FunMaker-5:~ root# ls -l /sbin/launchd
-r-xr-xr-x 1 root wheel 154736 Nov 8 2013 /sbin/launchd
so both a daemon and its config file must be owned by root too, it borns and runs as root. Take it in mind and we’ll get back to this later.

Part II Composing
As we have already stated in iOS App Reverse Engineering, daemons consists of 2 parts, an executable binary and a configuration plist file. So let’s make an executable binary with Theos now:

snakeninnys-MacBook:Code snakeninny$ /opt/theos/bin/nic.pl
NIC 2.0 - New Instance Creator

[1.] iphone/application
[2.] iphone/cydget
[3.] iphone/framework
[4.] iphone/library
[5.] iphone/notification_center_widget
[6.] iphone/preference_bundle
[7.] iphone/sbsettingstoggle
[8.] iphone/tool
[9.] iphone/tweak
[10.] iphone/xpc_service
Choose a Template (required): 8
Project Name (required): rootdaemond
Package Name [com.yourcompany.rootdaemond]: com.iosre.rootdaemond
Author/Maintainer Name [snakeninny]: snakeninny
Instantiating iphone/tool in rootdaemond/…
Done.
And modify the content of main.mm

static void Reboot(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
NSLog(@“iOSRE: reboot”);
system(“reboot”);
}

int main(int argc, char **argv, char **envp)
{
NSLog(@“iOSRE: rootdaemond is launched!”);
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, Reboot, CFSTR(“com.iosre.rootdaemon.reboot”), NULL, CFNotificationSuspensionBehaviorCoalesce);
CFRunLoopRun(); // keep it running in background
return 0;
}
This’s it. Now let’s turn to the config file, create a file with the name “com.iosre.rootdaemond.plist”, and fill it with the following contents:

<?xml version="1.0" encoding="UTF-8"?> KeepAlive Label com.iosre.rootdaemond Program /usr/bin/rootdaemond RunAtLoad Among those keys, Label "contains a unique string that identifies your daemon to launchd", Program contains the path of the executable, both of them are required. If you have arguments for the daemon, just add another key/value pair to the file like this:

ProgramArguments

arg1
arg2
more args…

After that we should put this config file under /Library/LaunchDaemons/, and we leave this job to “layout” folder, you definately know how if you are a careful reader. Our project looks like this: (2014.12.12 Edit: We should create an empty DEBIAN folder under layout)

Run “make package” and let’s check the owner of the deb:

snakeninnys-MacBook:rootdaemond snakeninny$ dpkg-deb -c /Users/snakeninny/Code/rootdaemond/com.iosre.rootdaemond_1.0-1_iphoneos-arm.deb
drwxr-xr-x snakeninny/staff 0 2014-05-11 15:52 ./
drwxr-xr-x snakeninny/staff 0 2014-05-11 14:45 ./Library/
drwxr-xr-x snakeninny/staff 0 2014-05-11 15:48 ./Library/LaunchDaemons/
-rwxr-xr-x snakeninny/staff 367 2014-05-11 15:37 ./Library/LaunchDaemons/com.iosre.rootdaemond.plist
drwxr-xr-x snakeninny/staff 0 2014-05-11 15:52 ./usr/
drwxr-xr-x snakeninny/staff 0 2014-05-11 15:52 ./usr/bin/
-rwxr-xr-x snakeninny/staff 197984 2014-05-11 15:52 ./usr/bin/rootdaemond
All files inside deb are owned by snakeninny:staff. Remember in the “Daemon ownership” part, daemons must be owned by root? So this daemon has wrong owner, which will lead to a load failure (you can try it out on your iOS).
You may wonde why? That’s because this deb is made on OSX, and the maker is snakeninny. To change its owner back to root:wheel, we need a tool called fauxsu by DHowett. Download a compiled version from here1, extract fauxsu and libfauxsu.dylib to $THEOS/bin/ and “chmod a+x” them. Make another package and check again (and also notice the edit at the end of this post):

snakeninnys-MacBook:rootdaemond snakeninny$ dpkg-deb -c /Users/snakeninny/Code/rootdaemond/com.iosre.rootdaemond_1.0-2_iphoneos-arm.deb
drwxr-xr-x root/wheel 0 2014-05-11 16:05 ./
drwxr-xr-x root/wheel 0 2014-05-11 14:45 ./Library/
drwxr-xr-x root/wheel 0 2014-05-11 15:48 ./Library/LaunchDaemons/
-rwxr-xr-x root/wheel 367 2014-05-11 15:37 ./Library/LaunchDaemons/com.iosre.rootdaemond.plist
drwxr-xr-x root/wheel 0 2014-05-11 16:05 ./usr/
drwxr-xr-x root/wheel 0 2014-05-11 16:05 ./usr/bin/
-rwxr-xr-x root/wheel 197984 2014-05-11 16:05 ./usr/bin/rootdaemond
Now the owner is correct. Run “make install” to setup this rootdaemond:

snakeninnys-MacBook:rootdaemond snakeninny$ make install
install.exec “cat > /tmp/_theos_install.deb; dpkg -i /tmp/_theos_install.deb && rm /tmp/_theos_install.deb” < “./com.iosre.rootdaemond_1.0-2_iphoneos-arm.deb”
Selecting previously deselected package com.iosre.rootdaemond.
(Reading database … 2589 files and directories currently installed.)
Unpacking com.iosre.rootdaemond (from /tmp/_theos_install.deb) …
Setting up com.iosre.rootdaemond (1.0-2) …
Again, the code can be downloaded here.

Part III Testing
Reboot to check if it’s launched on startup:

FunMaker-5:~ root# reboot
FunMaker-5:~ root# Connection to 192.168.1.101 closed by remote host.
Connection to 192.168.1.101 closed.
snakeninnys-MacBook:Code snakeninny$ ssh root@192.168.1.101
FunMaker-5:~ root# grep iOSRE /var/log/syslog
May 11 16:14:01 FunMaker-5 rootdaemond[20]: iOSRE: rootdaemond is launched!
FunMaker-5:~ root# ps -e | grep rootdaemond
20 ?? 0:00.13 /usr/bin/rootdaemond
370 ttys000 0:00.01 grep rootdaemond
FunMaker-5:~ root#
rootdaemond was started on boot, and it stays in the background. Finally, let’s check if it works as expected, with the following tester:

// compile: clang -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk -o iOSRERootDaemonTester -arch armv7 /Users/snakeninny/main.mm

#include <notify.h>

int main(int argc, char **argv)
{
notify_post(“com.iosre.rootdaemon.reboot”);
return 0;
}
Scp iOSRERootDaemonTester to iOS, then run it:

snakeninnys-MacBook:~ snakeninny$ scp iOSRERootDaemonTester root@192.168.1.101:/var/tmp/
iOSRERootDaemonTester 100% 48KB 48.3KB/s 00:00
FunMaker-5:~ root# /var/tmp/iOSRERootDaemonTester
FunMaker-5:~ root# Connection to 192.168.1.101 closed by remote host.
Connection to 192.168.1.101 closed.
snakeninnys-MacBook:Code snakeninny$ ssh root@192.168.1.101
FunMaker-5:~ root# grep iOSRE /var/log/syslog
May 11 16:36:01 FunMaker-5 rootdaemond[20]: iOSRE: reboot
May 11 16:36:58 FunMaker-5 rootdaemond[20]: iOSRE: rootdaemond is launched!
FunMaker-5:~ root#
It works like a charm.

Part IV Conclusion
Actually daemons and agents on iOS/OSX are far more complicated than this post describes, and I strongly suggest you take a look at the references below. Again, daemons are powerful tools that can do both good and bad, you’d better know what you’re doing before you use them, and you should be really careful when you use them. Thanks for your time.

References:

  1. http://en.wikipedia.org/wiki/Daemon_(computing)
  2. https://www.chrisalvares.com/blog/7/creating-an-iphone-daemon-part-1/
  3. https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/launchctl.1.html
  4. Creating Launch Daemons and Agents
  5. https://developer.apple.com/library/mac/documentation/Darwin/Reference/Manpages/man5/launchd.plist.5.html

2014.5.22 Edit:
com.iosre.rootdaemond.plist should have permission 644, or this daemon MAY NOT get launched!

2014.10.16编辑:
翻译版请至这里2~

我想拓展这个示例,加入我想要的功能,写一个较复杂的守护进程。
但由于没有使用theos编写过tool,以及编程基础较薄弱,所以遇到一些问题没能解决。

int plus(int a,int b)
{
    int c = 0;
    c = a + b;
    return c;
}

static void Reboot(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
    NSLog(@"iOSRE: myDaemond is launched!");
    
    int x = plus(2,3);
    NSLog(@"\n--------\n iOSRE: plus 2,3 is %d! \n--------\n",x);
    NSLog(@"--------\n reboot \n--------");
    
    //system("reboot");
}

int main(int argc, char **argv, char **envp)
{
    NSLog(@"iOSRE: rootdaemond is launched!");
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, Reboot, CFSTR("com.iosre.rootdaemon.reboot"), NULL, CFNotificationSuspensionBehaviorCoalesce);
    CFRunLoopRun(); // keep it running in background
    return 0;
}

这样做是没有问题的,但我不能吧所有代码都写在一个文件里啊!

没有强制要你把所有代码都写在一个文件里啊,你正常定义其他的h、m和mm文件,然后写就是了啊

所以我在文件夹建立了 文件夹a
其中新建了a.h:

//#include<stdio.h>

int plus(int a,int b);

为何注释掉“#include<stdio.h>”呢?因为使用“#include<stdio.h>”之类头文件会报大量错误,待会我会贴出所报错误,单独请教这个问题。

和a.m:

#include"a.h"

int plus(int a,int b)
{
    int c = 0;
    c = a + b;
    return c;
    
}

然后修改Makefile文件,在rootdaemond_FILES = 后添加 a/a.m
即:

include theos/makefiles/common.mk

TOOL_NAME = rootdaemond
rootdaemond_FILES = main.mm a/a.m

include $(THEOS_MAKE_PATH)/tool.mk

之后编译,make package

报错:

/Users/xxx/rootdaemond/theos/makefiles/targets/Darwin/iphone.mk:41: Deploying to iOS 3.0 while building for 6.0 will generate armv7-only binaries.
Making all for tool rootdaemond...
 Compiling main.mm...
 Compiling a/a.m...
 Linking tool rootdaemond...
Undefined symbols for architecture armv7:
  "plus(int, int)", referenced from:
      _main in main.mm.7fc69fbf.o
      Reboot(__CFNotificationCenter*, void*, __CFString const*, void const*, __CFDictionary const*) in main.mm.7fc69fbf.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [obj/rootdaemond.ba964c90.unsigned] Error 1
make[1]: *** [internal-tool-all_] Error 2
make: *** [rootdaemond.all.tool.variables] Error 2

**

  • :sweat: 查资料找到解决办法:将a.m改成a.mm*

**

继续尝试main.mm中添加“#import<UIKit/UIKit.h>”
Makefile中添加“rootdaemond_FRAMEWORKS = UIKit”
保存,make package。
报大量错误:

 0987deMacBook-Pro:xxx-rootdaemond d0987$ make package
Making all for tool rootdaemond...
In file included from main.mm:4:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:9:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAccelerometer.h:8:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:6:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CoreFoundation.h:11:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/sys/types.h:75:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/sys/cdefs.h:655:2: error: 
      Unsupported architecture
#error Unsupported architecture
 ^
In file included from main.mm:4:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:9:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAccelerometer.h:8:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:6:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CoreFoundation.h:11:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/sys/types.h:78:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/machine/types.h:37:2: error: 
      architecture not supported
#error architecture not supported
 ^
In file included from main.mm:4:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:9:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAccelerometer.h:8:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:6:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CoreFoundation.h:11:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/sys/types.h:79:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/sys/_types.h:33:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/machine/_types.h:34:2: error: 
      architecture not supported
#error architecture not supported
 ^
In file included from main.mm:4:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:9:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAccelerometer.h:8:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:6:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CoreFoundation.h:11:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/sys/types.h:81:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/machine/endian.h:37:2: error: 
      architecture not supported
#error architecture not supported
 ^
In file included from main.mm:4:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:9:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAccelerometer.h:8:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:6:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CoreFoundation.h:17:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/5.1/include/limits.h:38:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/limits.h:64:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/machine/limits.h:8:2: error: 
      architecture not supported
#error architecture not supported
 ^
In file included from main.mm:4:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:9:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAccelerometer.h:8:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:6:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CoreFoundation.h:21:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/signal.h:63:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/sys/signal.h:81:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/machine/signal.h:34:2: error: 
      architecture not supported
#error architecture not supported
 ^
In file included from main.mm:4:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:9:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAccelerometer.h:8:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:6:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CoreFoundation.h:21:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/signal.h:63:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/sys/signal.h:145:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/machine/_mcontext.h:31:2: error: 
      architecture not supported
#error architecture not supported
 ^
In file included from main.mm:4:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:9:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAccelerometer.h:8:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:6:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CoreFoundation.h:43:
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CFByteOrder.h:10:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/libkern/OSByteOrder.h:45:10: fatal error: 
      'libkern/machine/OSByteOrder.h' file not found
#include <libkern/machine/OSByteOrder.h>
         ^
8 errors generated.
 Compiling main.mm...
 Linking tool rootdaemond...
 Stripping rootdaemond...
 Signing rootdaemond...
Making stage for tool rootdaemond...
dpkg-deb:正在新建软件包“com.iosre.rootdaemond”,包文件为“./com.iosre.rootdaemond_0.0.1-59_iphoneos-arm.deb”。
0987deMacBook-Pro:xxx-rootdaemond d0987$ 

主要都是这一类错误:

In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CFByteOrder.h:10:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/libkern/OSByteOrder.h:45:10: fatal error: 
      'libkern/machine/OSByteOrder.h' file not found
#include <libkern/machine/OSByteOrder.h>
         ^

不知是不是没有正确的添加SDK造成的。

貌似错误主要出在这里吧,你的makefile是怎么写的?

ARCHS = armv7
TARGET = iPhone:7.1

include theos/makefiles/common.mk

TOOL_NAME = rootdaemond
rootdaemond_FILES = main.mm 
rootdaemond_FRAMEWORKS = UIKit

include $(THEOS_MAKE_PATH)/tool.mk

上面这是我的makefile,把ARCHS = armv7注销掉后报错没什么变化

你再加个arm64,写成

ARCHS = armv7 arm64

试试

1 个赞

解决了!谢

遇到这些类似问题,解决的思路是什么呢?除了经验以外,有什么好的参考书能解释这些问题呢?

注:我误删#import<UIKit/UIKit.h>导致产生编译正确的假象,抱歉。 :sweat:

编译时报的错就已经说明问题了,只是你没有好好看而已啊

错了,没解决,还是老样子,抱歉。
看来我得重头读theos/makefiles/common.mk和$(THEOS_MAKE_PATH)/tool.mk才行。

我发现我的环境变量中没有THEOS_MAKE_PATH,但又发现这个不是环境变量。是theos/makefiles/common.mk中定义的变量,

include $(THEOS_MAKE_PATH)/tool.mk

注释前后编译没有变化。

而且尝试阅读theos/makefiles/common.mk不现实,太复杂,

回到错误,发现8个错误其中7个相同,举一例:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/machine/_mcontext.h:31:2: error: 
      architecture not supported
#error architecture not supported

找到错误中出现的_mcontext.h打开,其内容为:

#if   defined (__arm__) || defined (__arm64__)
#include "arm/_mcontext.h"
#else
#error architecture not supported
#endif

说明问题出在: #if defined (__arm__) || defined (__arm64__)判断中都值为否,那么怎么通过makefile改变这个值呢?

theos/makefiles/common.mk中没有发现ARCHS变量
iphone.mk中有

如果是

#if defined (__arm__) || defined (__arm64__)

的话,应该在makefile中填armv7和arm64就够了啊,你先make cleanmake试试

不行,没有效果。

我发现不添加TARGET = iPhone:7.1也不会影响效果,

我通过搜索发现了3个iphone.mk:

/opt/theos/makefiles/targets/Darwin/iphone.mk
/opt/theos/makefiles/targets/Darwin-arm/iphone.mk
/opt/theos/makefiles/targets/Linux/iphone.mk

其中前两个比较靠谱,比如: /opt/theos/makefiles/targets/Darwin/iphone.mk

ifeq ($(_THEOS_TARGET_LOADED),)
_THEOS_TARGET_LOADED := 1
THEOS_TARGET_NAME := iphone

ifeq ($(__THEOS_TARGET_ARG_1),clang)
_THEOS_TARGET_CC := clang
_THEOS_TARGET_CXX := clang++
_THEOS_TARGET_ARG_ORDER := 2 3
else
_THEOS_TARGET_CC := gcc
_THEOS_TARGET_CXX := g++
_THEOS_TARGET_ARG_ORDER := 1 2
endif

# A version specified as a target argument overrides all previous definitions.
_SDKVERSION := $(or $(__THEOS_TARGET_ARG_$(word 1,$(_THEOS_TARGET_ARG_ORDER))),$(SDKVERSION))
_THEOS_TARGET_SDK_VERSION := $(or $(_SDKVERSION),latest)

_SDK_DIR := $(THEOS_PLATFORM_SDK_ROOT)/Platforms/iPhoneOS.platform/Developer/SDKs
_IOS_SDKS := $(sort $(patsubst $(_SDK_DIR)/iPhoneOS%.sdk,%,$(wildcard $(_SDK_DIR)/iPhoneOS*.sdk)))
_LATEST_SDK := $(word $(words $(_IOS_SDKS)),$(_IOS_SDKS))

ifeq ($(_THEOS_TARGET_SDK_VERSION),latest)
override _THEOS_TARGET_SDK_VERSION := $(_LATEST_SDK)
endif

# We have to figure out the target version here, as we need it in the calculation of the deployment version.
_TARGET_VERSION_GE_6_0 = $(call __simplify,_TARGET_VERSION_GE_6_0,$(shell $(THEOS_BIN_PATH)/vercmp.pl $(_THEOS_TARGET_SDK_VERSION) ge 6.0))
_TARGET_VERSION_GE_3_0 = $(call __simplify,_TARGET_VERSION_GE_3_0,$(shell $(THEOS_BIN_PATH)/vercmp.pl $(_THEOS_TARGET_SDK_VERSION) ge 3.0))
_THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION := $(or $(__THEOS_TARGET_ARG_$(word 2,$(_THEOS_TARGET_ARG_ORDER))),$(TARGET_IPHONEOS_DEPLOYMENT_VERSION),$(_SDKVERSION),3.0)

ifeq ($(_THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION),latest)
override _THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION := $(_LATEST_SDK)
endif

_DEPLOY_VERSION_GE_3_0 = $(call __simplify,_DEPLOY_VERSION_GE_3_0,$(shell $(THEOS_BIN_PATH)/vercmp.pl $(_THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION) ge 3.0))
_DEPLOY_VERSION_LT_4_3 = $(call __simplify,_DEPLOY_VERSION_LT_4_3,$(shell $(THEOS_BIN_PATH)/vercmp.pl $(_THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION) lt 4.3))

ifeq ($(_TARGET_VERSION_GE_6_0)$(_DEPLOY_VERSION_GE_3_0)$(_DEPLOY_VERSION_LT_4_3),111)
ifeq ($(ARCHS)$(_THEOS_TARGET_WARNED_DEPLOY),)
$(warning Deploying to iOS 3.0 while building for 6.0 will generate armv7-only binaries.)
export _THEOS_TARGET_WARNED_DEPLOY := 1
endif
endif

SYSROOT ?= $(THEOS_PLATFORM_SDK_ROOT)/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS$(_THEOS_TARGET_SDK_VERSION).sdk

TARGET_CC ?= xcrun -sdk iphoneos $(_THEOS_TARGET_CC)
TARGET_CXX ?= xcrun -sdk iphoneos $(_THEOS_TARGET_CXX)
TARGET_LD ?= xcrun -sdk iphoneos $(_THEOS_TARGET_CXX)
TARGET_STRIP ?= xcrun -sdk iphoneos strip
TARGET_STRIP_FLAGS ?= -x
TARGET_CODESIGN_ALLOCATE ?= "$(shell xcrun -sdk iphoneos -find codesign_allocate)"
TARGET_CODESIGN ?= ldid
TARGET_CODESIGN_FLAGS ?= -S

TARGET_PRIVATE_FRAMEWORK_PATH = $(SYSROOT)/System/Library/PrivateFrameworks

include $(THEOS_MAKE_PATH)/targets/_common/darwin.mk
include $(THEOS_MAKE_PATH)/targets/_common/darwin_flat_bundle.mk

ifeq ($(_TARGET_VERSION_GE_6_0),1) # >= 6.0 {
ifeq ($(_DEPLOY_VERSION_GE_3_0)$(_DEPLOY_VERSION_LT_4_3),11) # 3.0 <= Deploy < 4.3 {
	ARCHS ?= armv7
else # } else {
	ARCHS ?= armv7 armv7s
endif # }
else # } < 6.0 {
ifeq ($(_TARGET_VERSION_GE_3_0),1) # >= 3.0 {
	ARCHS ?= armv6 armv7
else # } < 3.0 {
	ARCHS ?= armv6
endif # }
endif # }

SDKFLAGS := -isysroot "$(SYSROOT)" $(foreach ARCH,$(ARCHS),-arch $(ARCH)) -D__IPHONE_OS_VERSION_MIN_REQUIRED=__IPHONE_$(subst .,_,$(_THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION)) -miphoneos-version-min=$(_THEOS_TARGET_IPHONEOS_DEPLOYMENT_VERSION)
_THEOS_TARGET_CFLAGS := $(SDKFLAGS)
_THEOS_TARGET_LDFLAGS := $(SDKFLAGS) -multiply_defined suppress

TARGET_INSTALL_REMOTE := $(_THEOS_TRUE)
_THEOS_TARGET_DEFAULT_PACKAGE_FORMAT := deb
endif

里面有判断sdk版本的语句。

有点乱,我感觉你把问题搞复杂了。
你现在的目的就是扩充一个daemon的功能是吧?
碰到的问题,用文字大体描述一下,是什么?

这是我的main.mm:

#import<UIKit/UIKit.h>

static void Reboot(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
    NSLog(@"iOSRE: myDaemond is launched!");

    NSLog(@"-------- iOSRE: reboot --------");
    
    //system("reboot");
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"diaoSir: myDaemond is launched!" message:nil delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
    [alert release];
}

int main(int argc, char **argv, char **envp)
{
    NSLog(@"iOSRE: rootdaemond is launched!");
    
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, Reboot, CFSTR("com.iosre.rootdaemon.reboot"), NULL, CFNotificationSuspensionBehaviorCoalesce);
    CFRunLoopRun(); // keep it running in background
    
    
    return 0;
}

这是我的makefile:

ARCHS = armv7s arm64
TARGET = iPhone:7.1

include theos/makefiles/common.mk

TOOL_NAME = rootdaemond
rootdaemond_FILES = main.mm

rootdaemond_FRAMEWORKS = UIKit Foundation

include $(THEOS_MAKE_PATH)/tool.mk

现在的情况是make会报8个错误,其中七个是:#error architecture not supported

如果我单纯吧#import<UIKit/UIKit.h>注释掉,可以编译不报错,安装启动一切顺利。

NSLog(@"-------- iOSRE: reboot --------");

顺利执行,但是不弹窗口。现在大致这个情况。

大哥,你出来,我保证不打死你。你知道什么是daemon吗?

好吧,我错了,咱不要在意这些细节。我只是想用弹窗举个简单的例子而已。这个不合适,我再找找其他例子。
对不住了狗老师。

daemon是没有界面的,根本就不能弹窗。如果NSLog输出了,那就说明daemon已经正常运行了。要进一步确认的话,你用一个NSTimer持续NSLog,看看效果就知道了

已经成功拓展daemon,实现了很多功能。
编译时报的那8个错误,并不会影响daemon的打包和运行。想不通。
我发现用object-c写的代码要用.m后缀,其中添加了c代码的话就要用.mm后缀。