Skip to content

Instantly share code, notes, and snippets.

@externvoid
Last active May 27, 2016 05:37
Show Gist options
  • Select an option

  • Save externvoid/0cd09762de1a70f6d0dc8b6ea82eaf0c to your computer and use it in GitHub Desktop.

Select an option

Save externvoid/0cd09762de1a70f6d0dc8b6ea82eaf0c to your computer and use it in GitHub Desktop.
Memory-layout-based hacking in swiftから抜粋(unsafe族へのヒントが判る)
@externvoid

externvoid commented May 25, 2016 •

Copy link
Copy Markdown
Author

どうやら、このコードでメモリダンプができているって事らしい。

UnsafePointerでC言語のポインタを表すらしい。こんな感じ、
C:

void myFunction(const int *myConstIntPointer);

Swift:

func myFunction(myConstIntPointer: UnsafePointer<Int32>)

Cの関数を呼び出しには、こうするって事なのか?ってことは、UnsafePointerは型を表し、UnsafePonter($0)でポインタの指している先に格納されている値を示しているって事なのか?
print(bytePointer.dynamicType) // UnsafePointer
bytePointerはポインタで、bytePoint[0]でバイト単位にアクセスできるって事らしい。添え字は幾らでも大きくできてしまう。例えば、bytePoint[99]は、Print文で表示させると、0だ。

関数withUnsafePointerは引数のclosureを呼び出す。呼び出す際に、引数をclosureへ引き渡す。DocsetsにはObj-C APIを呼び出すのに便利ってあるが、具体的に活用例が見つからん。こんな感じらしい、
void takesAnObject(void *theObject);
こんなCの関数をswiftから呼ぶには、

var test = 42
withUnsafePointer(&test, { (ptr: UnsafePointer<Int>) -> Void in
    var voidPtr: UnsafePointer<Void> = unsafeBitCast(ptr, UnsafePointer<Void>.self)
    takesAnObject(voidPtr)// <- ここで呼び出し
})

以下の3つは全て同じbytePointerを返す。たぶん、aPlaneインスタンスへのアドレスをInt8型のインスタンスへのアドレスへキャストしているだけだ。
1️⃣let bytePointer = withUnsafePointer(&aPlane) { UnsafePointer($0) }

2️⃣let bytePointer = withUnsafePointer(&aPlane) { ptr in
UnsafePointer(ptr)
}

3️⃣let bytePointer = withUnsafePointer(&aPlane) { ptr in
unsafeBitCast(ptr, UnsafePointer.self)
}

4️⃣var voidPtr: UnsafePointer = unsafeBitCast(&aPlane, UnsafePointer.self)
unsafeBitCast<T, U> -> U、T型のインスタンスと、メタタイプUを受け取り、U型のインスタンスを返す。

error: cannot invoke 'unsafeBitCast' with an argument list of type '(inout Vehicle, UnsafePointer.Type)'
var voidPtr: UnsafePointer = unsafeBitCast(&aPlane, UnsafePointer.self)
^
note: expected an argument list of type '(T, U.Type)'
var voidPtr: UnsafePointer = unsafeBitCast(&aPlane, UnsafePointer.self)

✳️unsafeBitCast関数
func unsafeBitCast<T, U>(x: T, _: U.Type) -> U

インスタンスをビット列と見なして型解釈し直して、インスタンスを返す。
インスタンスがアドレスであっても良い。その場合はアドレスが返る。

✳️withUnsafePointer関数
Useful for calling Objective-C APIs、ポインタを引数に取るAPIを呼ぶのに便利、例えばVoid型のポインタとか。withUnsafeMutablePointers型も仲間⁉️
必ず、アドレスを引数にとる⁉️アドレスの型変換ができる。void* -> char*とか⁉️

✳️UnsafePointer型(構造体)、アドレスを表す
memoryメソッドで値を返す。(アドレスにある値)
UnsafeMutablePointer型も仲間⁉️

⭕️truncatingBitPattern、Int族のコンストラクタに付いているラベル⁉️

⭕️windows,…とかってのはassociated valueってヤツで、Qiitaで検索するとヒットする。Switchで取り出すらしい。aPlane.windowsとかしてもNGだった。

✳️unsafeAddressOf関数、大域関数
func unsafeAddressOf(object: AnyObject) -> UnsafePointer
Returns an UnsafePointer to the storage used for object. There's not much you can do with this other than use it to identify the object.
「オブジェクトの特定以外の使い道はありません。」だって⁉️
let p = unsafeAddressOf(aPlane as! AnyObject) //この方法でアドレスを
//取得しようとしても、コンパイラが落ちる
//print(p)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment