LoginSignup
1
1

Ghidraに踊らされたのでポインタを復習しよう

Posted at

身内に向けてhackmdで書いた記事を移植

CTFをやってるとReverseの問題でデコンパイラのGhidraを使う機会があります。あるプログラムを読ませたときにこんなコードが返ってきました

local_28 = 0x6e34637b67616c66;
local_20 = 0x594f5345485f7427;
for (j = 0; j < 16; j = j + 1) {
      if (param_1[j] != *(char *)((long)&local_28 + (long)j)) {

星だらけで認識しにくい...
普段Cだのポインタを使う言語で開発しないのでちょっとすらすら読むには復習が必要そうです

&演算子

&てなんだっけと思ってググったらどうやらアドレス取得演算子らしいです。
すなわち&local_28てのはlocal_28変数の開始アドレスを返すわけだな。そんでもってそれをlong型にキャストしていると。

ポインタとデリファレンス

思い出してきたけど一応メモっておきましょう。

int *a

ていうのは単純にポインタだったはずです。
逆に、

*a

みたいなのはポインタの指すメモリの実値を取得するやつだったはず。これはデリファレンスというらしい。

つまり?

local_28 = 0x6e34637b67616c66;
local_20 = 0x594f5345485f7427;
for (j = 0; j < 16; j = j + 1) {
      if (param_1[j] != *(char *)((long)&local_28 + (long)j)) {

こいつについて考え直しましょう。
アセンブラを読む限りlocal_28local_20はどうやらスタック上で連続しているようです。
よんでいくと...

  1. local_28のアドレスを取得
  2. アドレスに対してfor文で1ずつ加算
  3. 1, 2で得られたアドレスをchar型のポインタとしてキャスト
  4. キャストしてできたポインタをデシリアライズ
    これによってlocal_28から16バイト分を1バイトずつ取り出してcharとしてparam_1と比較しているようです。

たしかにアセンブラをそのまま起こすとこんなかんじになっちゃいそう

ポインタと配列

今回の復習でポインタと配列の関係も理解しました。
a[1]みたいなのは

*((long)&a + (long) 型のサイズ*index)

みたいな感じであらわせるわけですね

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1