実験で正文/非文判定をするプログラムを書いた時に役に立ったものをつらつらとまとめていく。
std::ifstream in("filename.txt");
00000000004005e0 <printf@plt>:
4005e0: ff 25 3a 0a 20 00 jmp QWORD PTR [rip+0x200a3a] # 601020 <printf@GLIBC_2.2.5>
4005e6: 68 01 00 00 00 push 0x1 # rip+0x200a3a(601020) : 4005e6
4005eb: e9 d0 ff ff ff jmp 4005c0 <.plt>
////
0000000000400782 <main>:
4007bb: b8 00 00 00 00 mov eax,0x0
4007c0: e8 1b fe ff ff call 4005e0 <printf@plt>
4007c5: 48 8d 45 e0 lea rax,[rbp-0x20]
CKYアルゴリズムをC++で書いていた際に、std::vector<vector> cky という2次元vectorを用意し cky.number
というメンバに
数値を代入していたところ、ある座標が同じメモリアドレスをさしていたことが判明。
具体的には、
0x7fa877c02dd0 0x7fa877c02e38 0x7fa877c02ea0 0x7fa877c02f08 0x7fa877c02f70 0x7fa877c02fd8 0x7fa877c03040
0x7fa877c02ea8 0x7fa877c02f10 0x7fa877c02f78 0x7fa877c02fe0 0x7fa877c03048 0x7fa877c030b0
x86-64モード用の呼び出し規約では、浮動小数点数の受け渡しは
xMM0
などのレジスタを用います. メモリとxMM0
系のレジスタ間で値を転送する命令(MOVAPS
やMOVAPD
など)は、メモリ上の値が16バイト境界に配置されていることを要求します.
コンパイラは、関数呼び出し時のスタックポインタが16バイト整列されていることを前提に,MOVAPS
やMOVAPD
命令を発行します. また、他の関数を呼び出すときには必ずスタックポインタが16バイト整列するように調整する責任があります.
(http://uchan.hateblo.jp/entry/2018/02/16/232029)
CTFにおいては
0x10
の境界にないとき、system
等がmovaps
が原因で失敗する為、ret
で揃える事がある.
val String.lastChar: Char | |
get() = get(length - 1) | |
var StringBuilder.lastChar: Char | |
get() = get(length - 1) | |
set(value: Char) { | |
this.setCharAt(length - 1, value) | |
} | |
/* |
fun <T> MutableList<T>.swap(index1: Int, index2: Int) { | |
val tmp = this[index1] | |
this[index1] = this[index2] | |
this[index2] = tmp | |
} | |
/* | |
参考 |