温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

system 函数被废除的替代方法

发布时间:2020-07-19 04:44:19 来源:网络 阅读:868 作者:xcmer2005 栏目:安全技术

做越狱应用和插件开发,经常会调用 system 去执行系统命令,早在 Xcode 7,使用 system 函数提示警告:

'system' is deprecated: first deprecated in iOS 8.0 - Use posix_spawn APIs installd

只是警告,还是可以正常编译和使用,但是升级到 Xcode 9,system 函数就从 SDK 中移除了,不能再使用了,提示:

'system' is unavailable: not available on iOS

替代的方法一般有三种,第一种是使用 posix_spawn,代码如下:

pid_t pid; char *argv[] = {   "/bin/ls",  //path   "-al",     //parameter1   "/",       //parameter2   NULL };   posix_spawn(&pid, argv[0], NULL, NULL, argv, NULL);   printf("pid=%d,child pid = %d\n",getpid(),pid);   int stat; waitpid(pid,&stat,0); printf("stat is %d\n",stat);

第二种是使用 NSTask,代码如下:

NSTask *task = [[NSTask alloc] init]; task.launchPath = @"/bin/ls"; task.arguments = [NSArray arrayWithObjects:                   @"-al",                   @"/",                   nil]; [task launch]; [task waitUntilExit];

NSTask.h 头文件信息如下:

#import <Foundation/NSObject.h>   @class NSString, NSArray, NSDictionary;   @interface NSTask : NSObject   // Create an NSTask which can be run at a later time // An NSTask can only be run once. Subsequent attempts to // run an NSTask will raise. // Upon task death a notification will be sent //   { Name = NSTaskDidTerminateNotification; object = task; } //   - (instancetype)init;   // set parameters // these methods can only be done before a launch // if not set, use current // if not set, use current   // set standard I/O channels; may be either an NSFileHandle or an NSPipe - (void)setStandardInput:(id)input; - (void)setStandardOutput:(id)output; - (void)setStandardError:(id)error;   // get parameters @property (NS_NONATOMIC_IOSONLY, copy) NSString *launchPath; @property (NS_NONATOMIC_IOSONLY, copy) NSArray *arguments; @property (NS_NONATOMIC_IOSONLY, copy) NSDictionary *environment; @property (NS_NONATOMIC_IOSONLY, copy) NSString *currentDirectoryPath;   // get standard I/O channels; could be either an NSFileHandle or an NSPipe - (id)standardInput; - (id)standardOutput; - (id)standardError;   // actions - (void)launch;   - (void)interrupt; // Not always possible. Sends SIGINT. - (void)terminate; // Not always possible. Sends SIGTERM.   @property (NS_NONATOMIC_IOSONLY, readonly) BOOL suspend; @property (NS_NONATOMIC_IOSONLY, readonly) BOOL resume;   // status @property (NS_NONATOMIC_IOSONLY, readonly) int processIdentifier;  @property (NS_NONATOMIC_IOSONLY, getter=isRunning, readonly) BOOL running;   @property (NS_NONATOMIC_IOSONLY, readonly) int terminationStatus;   @end   @interface NSTask (NSTaskConveniences)   + (NSTask *)launchedTaskWithLaunchPath:(NSString *)path arguments:(NSArray *)arguments; // convenience; create and launch   - (void)waitUntilExit; // poll the runLoop in defaultMode until task completes   @end   FOUNDATION_EXPORT NSString * const NSTaskDidTerminateNotification;

如果非要调用 system 函数不可,那就使用第三种方法,找到 system 函数地址直接调用,方法参见: 动态调用函数,具体代码如下:

typedef int (*my_system) (const char *str); int call_system(const char *str){          //动态库路径     char *dylib_path = "/usr/lib/libSystem.dylib";     //打开动态库     void *handle = dlopen(dylib_path, RTLD_GLOBAL | RTLD_NOW);     if (handle == NULL) {         //打开动态库出错         fprintf(stderr, "%s\n", dlerror());     } else {         //获取 system 地址         my_system system = dlsym(handle, "system");                  //地址获取成功则调用         if (system) {                          int ret = system(str);             return ret;         }         dlclose(handle); //关闭句柄     }          return -1; }

这样 call_system 函数就相当于 system 的功能了,替换即可。


原文地址:https://www.exchen.net/ios-hacker-system-%E5%87%BD%E6%95%B0%E8%A2%AB%E5%BA%9F%E9%99%A4%E7%9A%84%E6%9B%BF%E4%BB%A3%E6%96%B9%E6%B3%95.html


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI