Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Analysis of iOS Mach anomaly and signal signal

2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly explains "iOS Mach anomalies and signal signal analysis". The content of the explanation is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "iOS Mach anomalies and signal signal analysis".

1. IOS Mach exception

1.1 XNU

Darwin is the operating system of Mac OS and iOS, while XNU is the kernel part of the Darwin operating system. XNU is a hybrid kernel, which has the characteristics of both macro kernel and micro kernel, and Mach is its micro kernel.

The Darwin operating system corresponds to the MacOS and iOS system version numbers as shown in the above figure. Mac can execute the following command to check the Darwin version number.

System_profiler SPSoftwareDataType

1.2 Mach

Mach: [Macrok], the operating system microkernel, is the design basis of many new operating systems.

There are several basic concepts in the Mach microkernel:

Tasks, an object that owns a set of system resources, allowing "thread" to execute in it.

Threads, the basic unit of execution, has the context of task and shares its resources.

A set of protected message queues for communication between Ports,task; task can send / receive data to any port.

Message, which has a collection of typed data objects, can only be sent to port.

1.3 simulate Mach Message transmission

● Mach offers a small amount of API and less introduction to Apple documentation.

/ / create a message queue in the kernel to get the corresponding port

Mach_port_allocate ()

/ / Grant task the specified permissions on port

Mach_port_insert_right ()

/ / by setting the parameter: MACH_RSV_MSG/MACH_SEND_MSG is used to receive / send mach message

Mach_msg ()

The following code simulates sending Message to Mach Port and processing after receiving Message:

● first calls createPortAndAddListener to create Mach Port

● calls sendMachPortMessage: sends a message to the created MachPort

Example of ● execution result:

2018-02-27 09 33 create a port 37.797435 0800 xxx [54456 Swiss 5198921] 41731

2018-02-27 09 33 37.797697 0800 xxx [54456 5198921]

2018-02-27 09 remote_port 33 remote_port 37.797870 0800 xxx [54456 frog 5199525] Receive a mach message:, remote_port: 0, local_port: 41731, exception code: 28672

● sample code:

/ / create Mach Port and listen for messages

+ (mach_port_t) createPortAndAddListener {

Mach_port_t server_port

Kern_return_t kr = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, & server_port)

Assert (kr = = KERN_SUCCESS)

NSLog (@ "create a port:% d", server_port)

Kr = mach_port_insert_right (mach_task_self (), server_port, server_port, MACH_MSG_TYPE_MAKE_SEND)

Assert (kr = = KERN_SUCCESS)

[self setMachPortListener:server_port]

Return server_port

}

+ (void) setMachPortListener: (mach_port_t) mach_port {

Dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ {

Mach_message mach_message

Mach_message.Head.msgh_size = 1024

Mach_message.Head.msgh_local_port = server_port

Mach_msg_return_t mr

While (true) {

Mr = mach_msg (& mach_message.Head)

MACH_RCV_MSG | MACH_RCV_LARGE

0

Mach_message.Head.msgh_size

Mach_message.Head.msgh_local_port

MACH_MSG_TIMEOUT_NONE

MACH_PORT_NULL)

If (mr! = MACH_MSG_SUCCESS & & mr! = MACH_RCV_TOO_LARGE) {

NSLog (@ "error!")

}

Mach_msg_id_t msg_id = mach_message.Head.msgh_id

Mach_port_t remote_port = mach_message.Head.msgh_remote_port

Mach_port_t local_port = mach_message.Head.msgh_local_port

NSLog (@ "Receive a mach message: [% d], remote_port:% d, local_port:% d, exception code:% d"

Msg_id

Remote_port

Local_port

Mach_message.exception)

Abort ()

}

});

}

/ / send a message to the specified Mach Port

+ (void) sendMachPortMessage: (mach_port_t) mach_port {

Kern_return_t kr

Mach_msg_header_t header

Header.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0)

Header.msgh_size = sizeof (mach_msg_header_t)

Header.msgh_remote_port = mach_port

Header.msgh_local_port = MACH_PORT_NULL

Header.msgh_id = 100

NSLog (@ "Send a mach message: [% d].", header.msgh_id)

Kr = mach_msg (& header)

MACH_SEND_MSG

Header.msgh_size

0

MACH_PORT_NULL

MACH_MSG_TIMEOUT_NONE

MACH_PORT_NULL)

}

1.4 catch Mach exception

● task_set_exception_ports () sets the Port for the kernel to receive Mach exception messages, and when replaced with a custom Port, the exception messages generated during program execution can be captured.

Example of ● execution result:

2018-02-27 09 xxx 52V 11.4830760800 xxx [55018V 5253531] create a port: 23299

2018-02-27 09 BAD MEM ACCESS 52v 14.484272v 0800 xxx [55018 BAD MEM ACCESS 5253531] * Make a [BAD MEM ACCESS] now. **********

2018-02-27 09 remote_port 52V 14.484477V 0800 xxx [55018V 5253611] Receive a mach message: [2405], remote_port: 23555, local_port: 23299, exception code: 1

● sample code:

+ (void) createAndSetExceptionPort {

Mach_port_t server_port

Kern_return_t kr = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, & server_port)

Assert (kr = = KERN_SUCCESS)

NSLog (@ "create a port:% d", server_port)

Kr = mach_port_insert_right (mach_task_self (), server_port, server_port, MACH_MSG_TYPE_MAKE_SEND)

Assert (kr = = KERN_SUCCESS)

Kr = task_set_exception_ports (mach_task_self (), EXC_MASK_BAD_ACCESS | EXC_MASK_CRASH, server_port, EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE)

[self setMachPortListener:server_port]

}

/ / construct BAD MEM ACCESS Crash

-(void) makeCrash {

NSLog (@ "* Make a [BAD MEM ACCESS] now. *")

* ((int *) (0x1234)) = 122

}

1.5 Runloop

The application of Mach Port is not only at the kernel level, but also at the Cocoa Foundation and Core Foundation layers, such as Runloop.

There are two categories of Runloop sources:

1.Input sources

Port-Based sources

Custom Input sources

2.Timer sources

Port-Based sources is based on Mach Port and completes message delivery in Runloop.

The above Mach API is the kernel layer exit interface, and the Cocoa Foundation and Core Foundation layers respectively encapsulate the Mach Port interface for calling. For more information: Apple-Runloop Programming Guard, there is a detailed sample code.

2. Signal signal

Signal is a soft interrupt signal that provides asynchronous event handling mechanism. Signal is a rough way to communicate information between processes, using scenarios:

Related to process termination

Terminal interaction

Related to programming errors or hardware errors, when the system encounters an unrecoverable error, it triggers a crash mechanism to make the program exit, such as division of 0, memory write error, and so on.

Here we mainly consider the signal-related applications when the system encounters an unrecoverable error, that is, Crash. Signal signal processing is a UNIX operating system mechanism, so the Android platform is also used in theory, and Android Native Crash can be captured based on signal.

2.1 signal registration and processing

Signal ()

# import

Register for signal handler

When the call is successful, the current operation of the signo signal is removed and replaced by a new signal handler specified by handler

The signal processing function returns void because there is no place for the function to return. Register the custom signal processing function, construct the Crash, send out the signal and execute the custom signal processing logic.

[attached]: when Xcode Debug is running, add breakpoints and execute the pro hand-p true-s false SIGABRT command before Crash triggers.

(lldb) pro hand-p true-s false SIGABRT

NAME PASS STOP NOTIFY

= =

SIGABRT true false true

2018-02-27 12 NSRangeException' now 57 Make 25.284651 0800 xxx [58061 NSRangeException' now 5651844]. **********

2018-02-27 12 NSRangeException', reason 57 NSSingleObjectArrayI objectAtIndex 25.294945 0800 xxx [58061 NSRangeException', reason 5651844] * NSSingleObjectArrayI objectAtIndex:: index 1 beyond bounds [0. 0]'

2018-02-27 12 handle signal 57 handle signal 25.888332 0800 xxx [58061 purl 5651844]-handle signal: 6

● sample code:

/ / set custom signal processing function

+ (void) setSignalHandler {

Signal (SIGABRT, test_signal_handler)

}

Static void test_signal_handler (int signo) {

NSLog (@ "[signal handler]-handle signal:% d", signo)

}

/ / construct NSRangeException exception to trigger SIGABRT signal transmission

-(void) makeCrash {

NSLog (@ "* Make a 'NSRangeException' now. *")

NSArray * array = @ [@ "aaa"]

}

2.2 LLDB Debugger

When running App in Xcode Debug mode, the signal of the App process is captured by the LLDB Debugger debugger; you need to use the LLDB debug command to throw the specified signal processing to the user layer to facilitate debugging.

● views all signaling configurations:

/ / process handle abbreviation

Pro hand

● modifies the specified signaling configuration:

/ / option:

/ /-P: PASS

/ /-S: STOP

/ /-N: NOTIFY

Pro hand-option false signal name

/ example: SIGABRT signal processing does not stop in LLDB, but can be thrown to the user layer

Pro hand-s false SIGABRT

2.3 reentrant

When sending a signal to the kernel, the process may execute anywhere in the code, for example, the process is performing an important operation, an inconsistent state may occur after an interruption, or the process is processing another signal. So make sure that the signal handler only performs reentrant operations:

When ● writes an interrupt handler, it is assumed that the interrupt process may be in a non-reentrant function.

● carefully modifies global data.

2.4 Advanced signal processing

The signal () function is very basic and provides only a minimum standard for signal management. The sigaction () system call provides more powerful signal management capabilities. When the signal processor is running, it can be used to block the reception of specific signals, and it can also be used to obtain information about the status of various operating systems and processes when the signal is sent.

● sample code:

/ / set custom signal processing function

+ (void) setSignalHandlerInAdvance {

Struct sigaction act

/ / when sa_flags is set to SA_SIGINFO, set sa_sigaction to specify the signal processing function

Act.sa_flags = SA_SIGINFO

Act.sa_sigaction = test_signal_action_handler

Sigaction (SIGABRT, & act, NULL)

}

Static void test_signal_action_handler (int signo, siginfo_t * si, void * ucontext) {

NSLog (@ "[sigaction handler]-handle signal:% d", signo)

/ / handle siginfo_t

NSLog (@ "siginfo: {\ nsi_signo:% d,\ nsi_errno:% d,\ nsi_code:% d,\ nsi_pid:% d,\ nsi_uid:% d,\ nsi_status:% d,\ nsi_value:% d\ n}"

Si- > si_signo

Si- > si_errno

Si- > si_code

Si- > si_pid

Si- > si_uid

Si- > si_status

Si- > si_value.sival_int)

}

Thank you for your reading, the above is the content of "iOS Mach anomaly and signal signal Analysis". After the study of this article, I believe you have a deeper understanding of iOS Mach anomaly and signal signal analysis, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report