• Stars
    star
    408
  • Rank 102,486 (Top 3 %)
  • Language
    Objective-C
  • License
    GNU General Publi...
  • Created almost 7 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

process info/monitoring library for macOS

ProcInfo

Proc Info is a open-source, user-mode, library for macOS. It provides simple interface to retrieve detailed information about running processes, plus allows one to asynchronously monitor process creation & exit events.

Love this library or want to support it? Check out my patreon page :)

Quick Start (tl;dr)

To use the Proc Info library:

  1. add the Proc Info library (lib/libprocInfo.a) and Apple's OpenBSM library (libbsm.tbd) to your Xcode Project
  2. import the Proc Info library header file (procInfo.h)
  3. instantiate a Proc Info object
  4. a) to retrieve information about a running process invoke the init: method
    b) to enumerate existing processes invoke the currentProcesses method
    c) to monitor process events, declare a callback block and invoke the start: method

...or just download the demo project, to take it for a spin!

#import "procInfo.h"

//init proc info object
// YES: skip (CPU-intensive) generation of code-signing info
// NO:  automatically generate code-signing info for each process
ProcInfo* procInfo = [[ProcInfo alloc] init:NO];

//dump process info for process 1337
NSLog(@"process: %@", [[Process alloc] init:1337]);

//dump process info for all processes
for(Process* process in [procInfo currentProcesses])
    NSLog(@"new process: %@", process);
   
//block for process events
ProcessCallbackBlock block = ^(Process* process)
{
    if(process.type != EVENT_EXIT)
       NSLog(@"process start: %@\n", process);
    
    else
      NSLog(@"process exit: %d\n", process.pid);
};

//start monitoring
// ->block will be invoke upon process events!
[procInfo start:block];
Details

The Proc Info library provides an interface to:

  • retrieve information about arbitrary processes (by pid)
  • retrieve information about all running processes
  • monitor for process start & exit events

The library is already used in various Objective-See's tools that:

  • need to track process creation events (e.g. RansomWhere? BlockBlock, etc)
  • classify running processes (based on their cryptographic signatures)

Moreover, it is an important component of tools designed to facilitate Mac malware analysis (e.g. OSX/FruitFly), and vulnerability hunting (e.g. Installers/Updaters).

As detailed in the 'Quick Start' section, to use Proc Info in your Xcode project perform the following steps.

1. Add the Proc Info library to your Xcode project:
To add the Proc Info library to your Xcode project simply drag and drop the library (lib/libprocInfo.a), into the File Navigator. In the resulting 'file add' popup, make sure the 'Copy items if needed' option is selected:

2. Add Apple's OpenBSM library to your Xcode project:
Select your project in Xcode, then click on the 'Build Phases' tab. In the 'Link Binary With Libraries' section, click the '+' to bring up the prompt for adding frameworks and libraries. Type bsm in the search box. Then select libbsm.tbd and click 'Add':

3. Add the 'Proc Info' library header file to your project:
In Xcode click, 'File' then 'Add Files to ' Browse to the location of the procInfo.h header file, and click 'Add.' Note, you can also add the procInfo.h file into your project simply by dragging and dropping it into Xcode.

Your Xcode project should now look something like this:

Hit Product->Build to compile and link your project. Assuming it cleanly builds, now it's time to start writing code to unlock the power of the Proc Info library :)

Before getting into coding specifics, its important to understand the Process and Binary objects. A Process object represents a instance of a running process. Looking at the header file procInfo.h one can see it contains information about the process such as:

  • pid
  • ppid
  • user
  • ancestors
  • arguments

Each Process object also has an associated Binary object that represents the on-disk image of the main executable which backs the process. The 'Binary' object contains information such as:

  • name
  • full path
  • file attributes
  • signing information

The signing information includes:

  • signing status
  • signing authorities
  • whether its an Apple binary
  • from the app store

With this information, one can use the library to answer questions such as:

  • "What are all running processes on my system that don't belong to Apple proper?"
  • "What are the arguments of the process that was just spawned?"
  • "Is that process from the Mac App Store?"
  • ...and many more!

Retrieving Information about an Arbitrary Process:

Via the Proc Info library one can create Process objects for arbitrary processes. Simply invoke the Process init: method with the process identifier (pid_t) of a running process:

//init process obj
Process* process = [[Process alloc] init:1337];

This will create a Process object for the specified process, that will contain the aforementioned process characteristics (ancestors, arguments, Binary object, etc). You can directly access this (e.g. process.binary.isApple). Here, we simply dump it to stdout via NSLog():

//dump process info
NSLog(@"process: %@", process);

//output
process: 
pid: 1337
path: /Applications/Calculator.app/Contents/MacOS/Calculator
user: 501
args: (
    "/Applications/Calculator.app/Contents/MacOS/Calculator"
)
ancestors: (
    557,
    554,
    353,
    1
)
binary: 
name: Calculator
path: /Applications/Calculator.app/Contents/MacOS/Calculator
attributes: {
    NSFileCreationDate = "2017-03-23 00:27:11 +0000";
    NSFileExtensionHidden = 0;
    NSFileGroupOwnerAccountID = 0;
    NSFileGroupOwnerAccountName = wheel;
    NSFileHFSCreatorCode = 0;
    NSFileHFSTypeCode = 0;
    NSFileModificationDate = "2017-03-23 00:27:11 +0000";
    NSFileOwnerAccountID = 0;
    NSFileOwnerAccountName = root;
    NSFilePosixPermissions = 493;
    NSFileReferenceCount = 1;
    NSFileSize = 199520;
    NSFileSystemFileNumber = 92435925;
    NSFileSystemNumber = 16777220;
    NSFileType = NSFileTypeRegular;
}
signing info: {
    signatureStatus = 0;
    signedByApple = 1;
    signingAuthorities =     (
        "Software Signing",
        "Apple Code Signing Certification Authority",
        "Apple Root CA"
    );
} (isApple: 1 / isAppStore: 0)

Retrieving Information about all Running Processes: The Proc Info library can also provide information about all running processes via the ProcInfo object's currentProcesses method. This method returns an array of Process objects; one for each running process:

//enum all existing procs
for(Process* process in [processInfo currentProcesses])
{
     //query/examine each process...

     //dump process info
     NSLog(@"process: %@", process);
}

Note that this method may take a few seconds to execute, as generating and verifying the cryptographic signing information for all processes is somewhat time/CPU consuming. As such, it is recommended that you invoke this logic (i.e. the currentProcesses method) on a background thread.

Monitoring Process Start and Exit Events: One of the most powerful features of the Proc Info library is its ability to asynchronously monitor for process events such as creation (exec, spawn, fork) and exit. When running with root privileges (recommended!) it uses Apple BSM auditing events to such process events. (For background on BSM auditing see "OpenBSM auditd on OS X: these are the logs you are looking for".

In order to begin monitoring for such events first declare a block to pass to the library. This block's type should be ProcessCallbackBlock which has been typedef'd in the procInfo.h header file as:

typedef void (^ProcessCallbackBlock)(Process*);

From this typedef, one can see this block will invoked with a pointer to a Process object, which is (as expected) represents the process which triggered the event. After creating a callback block, simply invoke the Proc Info start: method, passing in the block. This will kickoff asynchronous process monitoring. Now, anytime a process creation or exit event occurs, the code in the block will be automatically invoked!

One can be query returned Process object for the event type (EVENT_FORK, EVENT_EXIT, etc). If the event was not an exit event, the Process object will be fully instantiated, thus containing information such as ancestors, arguments, Binary object, etc. Note that for EVENT_EXIT events, the Process object will only contain the process identifier (pid) and the processes exit code.

Below is some example code that will call into the Proc Info library to asynchronously monitor for process events. Once the library detects such events, it will automatically invoke the passed in block which here, just examines the event type and then dumps information about the process to stdout:

//define block
// ->automatically invoked upon process events
ProcessCallbackBlock block = ^(Process* process)
{
    //process start event
    // ->fork, spawn, exec, etc.
    if(process.type != EVENT_EXIT)
    {
        //print
        NSLog(@"process start: %@\n", process);
    }
    //process exit event
    else
    {
        //print
        // ->only pid
        NSLog(@"process exit: %d\n", process.pid);
    }
};

//start monitoring
// ->pass in block for events
[processInfo start:block];

//run loop
// ->as don't want to exit
[[NSRunLoop currentRunLoop] run];

Executing this code, and starting a process such as Calculator.app results in the following output:

# ./procInfoExample:

process start: 
pid: 1337
path: /Applications/Calculator.app/Contents/MacOS/Calculator
user: 501
args: (
    "/Applications/Calculator.app/Contents/MacOS/Calculator"
)
ancestors: (
    557,
    554,
    353,
    1
)
binary: name: Calculator
path: /Applications/Calculator.app/Contents/MacOS/Calculator
attributes: {
    NSFileCreationDate = "2017-03-23 00:27:11 +0000";
    NSFileExtensionHidden = 0;
    NSFileGroupOwnerAccountID = 0;
    NSFileGroupOwnerAccountName = wheel;
    NSFileHFSCreatorCode = 0;
    NSFileHFSTypeCode = 0;
    NSFileModificationDate = "2017-03-23 00:27:11 +0000";
    NSFileOwnerAccountID = 0;
    NSFileOwnerAccountName = root;
    NSFilePosixPermissions = 493;
    NSFileReferenceCount = 1;
    NSFileSize = 199520;
    NSFileSystemFileNumber = 92435925;
    NSFileSystemNumber = 16777220;
    NSFileType = NSFileTypeRegular;
}
signing info: {
    signatureStatus = 0;
    signedByApple = 1;
    signingAuthorities =     (
        "Software Signing",
        "Apple Code Signing Certification Authority",
        "Apple Root CA"
    );
} (isApple: 1 / isAppStore: 0)
2017-08-07 08:49:02.199 procInfoExample[10393:3296896] process exit: 1337

It should be noted that if the Proc Info library is not running with root privileges, or is executed on an older version of macOS (pre 10.12.4) it will only monitor for application events (i.e. not terminal nor background processes). This is because in order to safely monitor for audit events, root and recent version of macOS is required.

Mahalo!
This product is supported by the following patrons:

  • Halo Privacy

  • Ash Morgan

  • Nando Mendonca

  • Khalil Sehnaoui

  • Jeff Golden

  • Geoffrey Weber

  • Ming

  • Peter Sinclair

  • trifero

  • Keelian Wardle

  • Chad Collins

  • Shain Singh

  • David Sulpy

  • Martin OConnell

  • Bill Smartt

  • Mike Windham

  • Brent Joyce

  • Russell Imrie

  • Michael Thomas

  • Andy One

  • Edmund Harriss

  • Brad Knowles

  • Tom Smith

  • Chuck Talk

  • Derivative Fool

  • Joaquim Espinhara

  • Rudolf Coetzee

  • Chris Ferebee

  • Les Aker

  • Allen Hancock

  • Stuart Ashenbrenner

  • Gamer_Bot

Want to add your support? Check out my patreon page :)

More Repositories

1

LuLu

LuLu is the free macOS firewall
Objective-C
9,011
star
2

BlockBlock

BlockBlock provides continual protection by monitoring persistence locations.
Objective-C
579
star
3

OverSight

OverSight monitors a mac's mic and webcam, alerting the user when the internal mic is activated, or whenever a process accesses the webcam.
Objective-C
435
star
4

ProcessMonitor

Process Monitor Library (based on Apple's new Endpoint Security Framework)
Objective-C
398
star
5

KnockKnock

Enumerate persistently installed software
Objective-C
364
star
6

ReiKey

Malware and other applications may install persistent keyboard "event taps" to intercept your keystrokes. ReiKey can scan, detect, and monitor for such taps!
Objective-C
316
star
7

FileMonitor

File Monitor Library (based on Apple's new Endpoint Security Framework)
Objective-C
307
star
8

DoNotDisturb

Detect Evil Maid Attacks
Objective-C
285
star
9

Netiquette

Network Monitor
Objective-C
278
star
10

WhatsYourSign

WhatsYourSign adds a menu item to Finder.app. Simply right-, or control-click on any file to display its cryptographic signing information!
Objective-C
259
star
11

Malware

macOS Malware Collection
207
star
12

sniffMK

sniff mouse and keyboard events
Objective-C
205
star
13

DNSMonitor

A DNS Monitor, leveraging Apple's NEDNSProxyProvider/Network Extension Framework
Objective-C
143
star
14

DumpBTM

And open-source version of % sfltool dumpbtm
Objective-C
97
star
15

AuRevoir

View and remove notification messages from Apple's "Notification Database"
Objective-C
94
star
16

TaskExplorer

Visually explore all running tasks (processes) ....viewing its signature status, loaded dylibs, open files, network connection, and much more.
Objective-C
76
star
17

DylibHijackScanner

Scan your computer for applications that are either susceptible to dylib hijacking or have been hijacked.
Objective-C
73
star
18

ProcInfoExample

example project, utilizing Proc Info library
Objective-C
66
star
19

fromAppStore

checks if an application is pristine (untampered) and from the official Mac App Store
Objective-C
65
star
20

RansomWhere

Generic ransomware detector
Objective-C
64
star
21

KextViewr

View all modules on that are loaded in the OS kernel
Objective-C
61
star
22

Mach-O

A (basic) Mach-O Library
Objective-C
20
star
23

objective-see

19
star
24

LockDown

Audits and remediates security configuration settings (El Capitan)
Objective-C
15
star
25

products

Objective-See's Products
11
star
26

Ostiarius

Blocks unsigned internet binaries from executing (El Capitan)
Objective-C
8
star