11 KiB
macOS GCD - Grand Central Dispatch
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- サイバーセキュリティ企業で働いていますか? HackTricksで会社を宣伝したいですか?または、PEASSの最新バージョンにアクセスしたり、HackTricksをPDFでダウンロードしたいですか?SUBSCRIPTION PLANSをチェックしてください!
- The PEASS Familyを見つけてください。独占的なNFTのコレクションです。
- 公式のPEASS&HackTricks swagを手に入れましょう。
- 💬 Discordグループまたはtelegramグループに参加するか、Twitterでフォローしてください🐦@carlospolopm。
- ハッキングのトリックを共有するには、PRを hacktricks repo と hacktricks-cloud repo に提出してください。
基本情報
Grand Central Dispatch (GCD)、またはlibdispatchは、macOSとiOSの両方で利用可能な技術です。これは、Appleが開発したもので、マルチコアハードウェア上での並行(マルチスレッド)実行を最適化するためのアプリケーションサポートを提供します。
GCDは、アプリケーションがブロックオブジェクトの形でタスクをディスパッチキューに送信できるFIFOキューを提供し、システムによって完全に管理されるスレッドプール上で実行されます。GCDは、ディスパッチキュー内のタスクを実行するためにスレッドを自動的に作成し、利用可能なコア上でそれらのタスクをスケジュールします。
{% hint style="success" %} 要約すると、並行してコードを実行するために、プロセスはコードのブロックをGCDに送信し、その実行をGCDに任せます。したがって、プロセスは新しいスレッドを作成しません。GCDは独自のスレッドプールで指定されたコードを実行します。 {% endhint %}
これは、並行実行を成功裏に管理するために非常に役立ちます。プロセスが作成するスレッドの数を大幅に減らし、並行実行を最適化することができます。これは、大規模な並行性(ブルートフォース?)を必要とするタスクや、メインスレッドをブロックしてはならないタスクに非常に適しています。たとえば、iOSのメインスレッドはUIのインタラクションを処理するため、アプリがフリーズする可能性のある他の機能(検索、Webへのアクセス、ファイルの読み取りなど)はこの方法で処理されます。
Objective-C
Objective-Cでは、ブロックを並行して実行するためのさまざまな関数があります。
- dispatch_async:非同期にブロックをディスパッチキューに送信し、すぐに戻ります。
- dispatch_sync:ブロックオブジェクトを実行し、そのブロックの実行が終了した後に戻ります。
- dispatch_once:アプリケーションのライフサイクルでブロックオブジェクトを1回だけ実行します。
- dispatch_async_and_wait:作業アイテムを実行し、その実行が終了するまで戻りません。
dispatch_sync
とは異なり、この関数はキューのすべての属性を尊重してブロックを実行します。
これらの関数は、次のパラメータを受け取ります:dispatch_queue_t
queue
、dispatch_block_t
block
これがブロックの構造体です:
struct Block {
void *isa; // NSConcreteStackBlock,...
int flags;
int reserved;
void *invoke;
struct BlockDescriptor *descriptor;
// captured variables go here
};
そして、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
は、元々Cで書かれたGrand Central Dispatch(GCD)フレームワークへのSwiftバインディングを提供するライブラリです。
**libswiftDispatch
**ライブラリは、CのGCD APIをよりSwiftに適したインターフェースでラップし、Swift開発者が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"))
コード例:
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
以下のFridaスクリプトは、複数のdispatch
関数にフックして、キュー名、バックトレース、およびブロックを抽出するために使用できます: 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
現在、GhidraはObjectiveCの**dispatch_block_t
構造体やswift_dispatch_block
**構造体を理解していません。
したがって、それらを理解させるためには、単に宣言するだけで十分です。
次に、コード内でそれらが使用されている場所を見つけます:
{% hint style="success" %} "block"という言葉が参照されている箇所をすべて注意深く確認し、構造体が使用されていることを理解してください。 {% endhint %}
変数を右クリックして、**swift_dispatch_block
**を選択して変数の型を変更します:
Ghidraは自動的にすべてを書き換えます:
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- サイバーセキュリティ企業で働いていますか? HackTricksで会社を宣伝したいですか?または、PEASSの最新バージョンにアクセスしたり、HackTricksをPDFでダウンロードしたいですか?SUBSCRIPTION PLANSをチェックしてください!
- The PEASS Familyを見つけてください。独占的なNFTのコレクションです。
- 公式のPEASS&HackTricksグッズを手に入れましょう。
- 💬 DiscordグループまたはTelegramグループに参加するか、Twitterで私をフォローしてください🐦@carlospolopm。
- ハッキングのトリックを共有するには、hacktricks repo と hacktricks-cloud repo にPRを提出してください。