プロセスの引数を取得する

前回の続き。KERN_PROCARGS2で引数の情報も取得出来た。但し自分(mobile)がオーナーのプロセスのみ。rootで動ければ全部取れるかも。

KERN_PROCARGSの方も試してみたけどiOS上ではうまく動かない(エミュレータなら環境変数まで取れたけど。)

KERN_PROCARGS2はバッファの先頭に引数の数(argc)が入っていて、あとは引数が文字列で('\0'区切りで)入っている。信用してprintf/strlenで中身を手繰っている。

参考: 「blog: pawo: 実行中のアプリケーションの引数リストを取得する (2)

#include <sys/sysctl.h>
#include <pwd.h>

#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))

void
show_processes()
{
    int mib_proc[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; // all processes
    struct kinfo_proc *procs;
    size_t buffersize = 0;
    int index, count;
    
    // get required buffer size for procs
    if (sysctl(mib_proc, ARRAY_SIZE(mib_proc), NULL, &buffersize, NULL, 0) < 0) {
        // failure calling sysctl()
        return;
    }
    procs = (struct kinfo_proc *)malloc(buffersize);
    // get procs info
    if (sysctl(mib_proc, ARRAY_SIZE(mib_proc), procs, &buffersize, NULL, 0) < 0) {
        // failure calling sysctl()
        free(procs);
        return;
    }
    count = buffersize / sizeof(struct kinfo_proc);

    // get required buffer size for arguments
    int mibargmax[] = { CTL_KERN, KERN_ARGMAX};
    int size_argmax = 0;
    size_t size = sizeof(size_argmax);
    if(sysctl(mibargmax, ARRAY_SIZE(mibargmax), &size_argmax, &size, NULL, 0) == -1) {
        // failure calling sysctl()
        free(procs);
        return;
    }
    char *arguments = malloc(size_argmax + 1);
    
    printf("UID             PID   PPID COMMAND\n");
    for (index = 0; index < count; index++) {
        uid_t p_uid = procs[index].kp_eproc.e_pcred.p_ruid;
        char *username = user_from_uid(p_uid, 0);
        pid_t p_pid = procs[index].kp_proc.p_pid;
        pid_t e_ppid = procs[index].kp_eproc.e_ppid;
        char *p_comm = procs[index].kp_proc.p_comm;
        printf("%-14s %5d %5d", username, p_pid, e_ppid);
        
        int mib[] = { CTL_KERN, KERN_PROCARGS2, p_pid};
        size_t arguments_size = size_argmax;
        if (sysctl(mib, ARRAY_SIZE(mib), arguments, &arguments_size, NULL, 0) != -1) {
            arguments[arguments_size] = '\0';
            int number_of_arguments;
            memcpy(&number_of_arguments, arguments, sizeof(number_of_arguments));
            char *arg_ptr = arguments + sizeof(number_of_arguments);
            while (number_of_arguments--) {
                printf(" %s", arg_ptr);
                arg_ptr += strlen(arg_ptr) + 1;
            }
            printf("\n");
        } else {
            printf(" %s\n", p_comm);
        }
    }
    free(arguments);
    free(procs);
    return;
}
UID             PID   PPID COMMAND
mobile         19193     1 /System/Library/CoreServices/CFNetworkAgent
root           19192     1 amfid
mobile         19191 19187 /var/mobile/Applications/BCAB6052-D9F7-4F52-9496-5F102EDC93B0/True3DMaze4i.app/True3DMaze4i
mobile         19190     1 /System/Library/PrivateFrameworks/iTunesStore.framework/Support/itunesstored
mobile         19187 19176 /Developer/usr/bin/debugserver 
mobile         19186 19176 /usr/libexec/springboardservicesrelay
mobile         19182     1 /usr/libexec/lsd
mobile         19178     1 /usr/libexec/installd  
root           19176     1 lockbot
_securityd     19175     1 securityd
mobile         19165     1 /usr/libexec/atc
mobile         19144     1 /usr/libexec/syslog_relay 
mobile         19143     1 /usr/libexec/notification_proxy
mobile         19139     1 /usr/libexec/notification_proxy
mobile         19138     1 /usr/libexec/notification_proxy
mobile         19130     1 /usr/libexec/afcd   /usr/libexec/afcd --lockdown -d
mobile         19117     1 /usr/libexec/ptpd  
mobile         13372     1 /Developer/usr/bin/debugserver 
mobile          7645     1 /System/Library/PrivateFrameworks/GeoServices.framework/geod
mobile          6662     1 /var/mobile/Applications/4335AC47-9753-4D5E-BF9F-52507E510B8C/iBooks.app/iBooks
mobile          6640     1 /Applications/MobileSafari.app/MobileSafari
mobile          6635     1 /System/Library/PrivateFrameworks/Ubiquity.framework/Versions/A/Support/ubd
root            6634     1 filecoordination
mobile          5744     1 /Applications/MobileMail.app/MobileMail
mobile          5579     1 /Applications/MobileSlideShow.app/MobileSlideShow
mobile          5394     1 /Applications/MobileStore.app/MobileStore
mobile          5390     1 /Applications/AppStore.app/AppStore
root             502     1 SCHelper
mobile           488     1 /Applications/Preferences.app/Preferences
mobile           321     1 /System/Library/Frameworks/AssetsLibrary.framework/Support/assetsd
mobile           145     1 /Applications/MobilePhone.app/MobilePhone
mobile           141     1 /usr/sbin/absinthed.K93
mobile            82     1 /System/Library/PrivateFrameworks/DataAccess.framework/Support/dataaccessd
mobile            81     1 /usr/sbin/aosnotifyd
root              70     1 networkd
mobile            67     1 /System/Library/CoreServices/SpringBoard.app/SpringBoard
mobile            63     1 /usr/sbin/BTServer
mobile            58     1 /System/Library/PrivateFrameworks/AggregateDictionary.framework/Support/aggregated
mobile            57     1 /System/Library/PrivateFrameworks/ApplePushService.framework/apsd
mobile            52     1 /usr/sbin/fairplayd.K93
root              51     1 fseventsd
mobile            49     1 /System/Library/PrivateFrameworks/IAP.framework/Support/iapd
mobile            48     1 /System/Library/PrivateFrameworks/IMCore.framework/imagent.app/imagent
root              46     1 locationd
_mdnsresponder    45     1 mDNSResponder
mobile            44     1 /System/Library/PrivateFrameworks/MediaRemote.framework/Support/mediaremoted
mobile            43     1 /usr/sbin/mediaserverd
root              27     1 wifid
root              23     1 powerd
root              21     1 lockdownd
_wireless         19     1 CommCenterClassi
root              16     1 syslogd
root              14     1 configd
root              13     1 notifyd
root              12     1 UserEventAgent
root               1     0 launchd
root               0     0 kernel_task