9.3 KiB
macOS GCD - Grand Central Dispatch
Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!
Otras formas de apoyar a HackTricks:
- Si quieres ver tu empresa anunciada en HackTricks o descargar HackTricks en PDF revisa los PLANES DE SUSCRIPCIÓN!
- Consigue el merchandising oficial de PEASS & HackTricks
- Descubre La Familia PEASS, nuestra colección de NFTs exclusivos
- Únete al 💬 grupo de Discord o al grupo de telegram o sígueme en Twitter 🐦 @carlospolopm.
- Comparte tus trucos de hacking enviando PRs a los repositorios de github de HackTricks y HackTricks Cloud.
Información Básica
Grand Central Dispatch (GCD), también conocido como libdispatch, está disponible tanto en macOS como en iOS. Es una tecnología desarrollada por Apple para optimizar el soporte de aplicaciones para la ejecución concurrente (multihilo) en hardware multicore.
GCD proporciona y gestiona colas FIFO a las que tu aplicación puede enviar tareas en forma de objetos de bloque. Los bloques enviados a las colas de despacho son ejecutados en un grupo de hilos completamente gestionado por el sistema. GCD crea automáticamente hilos para ejecutar las tareas en las colas de despacho y programa esas tareas para que se ejecuten en los núcleos disponibles.
{% hint style="success" %} En resumen, para ejecutar código en paralelo, los procesos pueden enviar bloques de código a GCD, que se encargará de su ejecución. Por lo tanto, los procesos no crean nuevos hilos; GCD ejecuta el código dado con su propio grupo de hilos. {% endhint %}
Esto es muy útil para gestionar la ejecución paralela con éxito, reduciendo en gran medida el número de hilos que crean los procesos y optimizando la ejecución paralela. Esto es ideal para tareas que requieren gran paralelismo (¿fuerza bruta?) o para tareas que no deberían bloquear el hilo principal: Por ejemplo, el hilo principal en iOS maneja las interacciones de la UI, así que cualquier otra funcionalidad que pudiera hacer que la aplicación se cuelgue (buscar, acceder a una web, leer un archivo...) se gestiona de esta manera.
Objective-C
En Objective-C hay diferentes funciones para enviar un bloque para ser ejecutado en paralelo:
- dispatch_async: Envía un bloque para ejecución asincrónica en una cola de despacho y retorna inmediatamente.
- dispatch_sync: Envía un objeto de bloque para ejecución y retorna después de que ese bloque termine de ejecutarse.
- dispatch_once: Ejecuta un objeto de bloque solo una vez durante la vida de una aplicación.
- dispatch_async_and_wait: Envía un elemento de trabajo para ejecución y retorna solo después de que termine de ejecutarse. A diferencia de
dispatch_sync
, esta función respeta todos los atributos de la cola cuando ejecuta el bloque.
Estas funciones esperan estos parámetros: dispatch_queue_t
queue,
dispatch_block_t
block
Esta es la estructura de un Bloque:
struct Block {
void *isa; // NSConcreteStackBlock,...
int flags;
int reserved;
void *invoke;
struct BlockDescriptor *descriptor;
// captured variables go here
};
Y este es un ejemplo de uso de paralelismo con dispatch_async
:
#import <Foundation/Foundation.h>
// Define a block
void (^backgroundTask)(void) = ^{
// Code to be executed in the background
for (int i = 0; i < 10; i++) {
NSLog(@"Background task %d", i);
sleep(1); // Simulate a long-running task
}
};
int main(int argc, const char * argv[]) {
@autoreleasepool {
// Create a dispatch queue
dispatch_queue_t backgroundQueue = dispatch_queue_create("com.example.backgroundQueue", NULL);
// Submit the block to the queue for asynchronous execution
dispatch_async(backgroundQueue, backgroundTask);
// Continue with other work on the main queue or thread
for (int i = 0; i < 10; i++) {
NSLog(@"Main task %d", i);
sleep(1); // Simulate a long-running task
}
}
return 0;
}
Swift
libswiftDispatch
es una biblioteca que proporciona enlaces Swift al framework Grand Central Dispatch (GCD), que originalmente está escrito en C.
La biblioteca libswiftDispatch
envuelve las APIs de GCD en C en una interfaz más amigable para Swift, facilitando y haciéndolo más intuitivo para los desarrolladores de Swift trabajar con GCD.
DispatchQueue.global().sync{ ... }
DispatchQueue.global().async{ ... }
let onceToken = DispatchOnce(); onceToken.perform { ... }
async await
var (data, response) = await URLSession.shared.data(from: URL(string: "https://api.example.com/getData"))
Ejemplo de código:
import Foundation
// Define a closure (the Swift equivalent of a block)
let backgroundTask: () -> Void = {
for i in 0..<10 {
print("Background task \(i)")
sleep(1) // Simulate a long-running task
}
}
// Entry point
autoreleasepool {
// Create a dispatch queue
let backgroundQueue = DispatchQueue(label: "com.example.backgroundQueue")
// Submit the closure to the queue for asynchronous execution
backgroundQueue.async(execute: backgroundTask)
// Continue with other work on the main queue
for i in 0..<10 {
print("Main task \(i)")
sleep(1) // Simulate a long-running task
}
}
Frida
El siguiente script de Frida puede ser utilizado para engancharse a varias funciones de dispatch
y extraer el nombre de la cola, el backtrace y el bloque: https://github.com/seemoo-lab/frida-scripts/blob/main/scripts/libdispatch.js
frida -U <prog_name> -l libdispatch.js
dispatch_sync
Calling queue: com.apple.UIKit._UIReusePool.reuseSetAccess
Callback function: 0x19e3a6488 UIKitCore!__26-[_UIReusePool addObject:]_block_invoke
Backtrace:
0x19e3a6460 UIKitCore!-[_UIReusePool addObject:]
0x19e3a5db8 UIKitCore!-[UIGraphicsRenderer _enqueueContextForReuse:]
0x19e3a57fc UIKitCore!+[UIGraphicsRenderer _destroyCGContext:withRenderer:]
[...]
Ghidra
Actualmente Ghidra no entiende ni la estructura dispatch_block_t
de ObjectiveC, ni la swift_dispatch_block
.
Así que si quieres que las entienda, podrías simplemente declararlas:
Luego, encuentra un lugar en el código donde se utilicen:
{% hint style="success" %} Toma nota de todas las referencias hechas a "block" para entender cómo podrías descubrir que la estructura se está utilizando. {% endhint %}
Haz clic derecho en la variable -> Retype Variable y selecciona en este caso swift_dispatch_block
:
Ghidra reescribirá automáticamente todo:
Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!
Otras formas de apoyar a HackTricks:
- Si quieres ver a tu empresa anunciada en HackTricks o descargar HackTricks en PDF consulta los PLANES DE SUSCRIPCIÓN!
- Consigue el merchandising oficial de PEASS & HackTricks
- Descubre La Familia PEASS, nuestra colección de NFTs exclusivos
- Únete al 💬 grupo de Discord o al grupo de telegram o sigue a Twitter 🐦 @carlospolopm.
- Comparte tus trucos de hacking enviando PRs a los repositorios de GitHub HackTricks y HackTricks Cloud.