---
# System prepended metadata

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

---

# Ghidra君に踊らされたのでポインタを復習しよう
CTFをやってるとReverseの問題でデコンパイラのGhidraを使う機会があるのですが、あるプログラムを読ませたときにこんなコードが返ってきました
星だらけで認識しにくい...
普段Cだのポインタを使う言語で開発しないのでちょっとすらすら読むには復習が必要そうです

```
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_28てのはlocal_28変数の開始アドレスを返すわけだな。そんでもってそれをlong型にキャストしていると。

## ポインタとデシリアライズ
思い出してきたけど一応メモっておきましょう。
```
int *a
```
ていうのは単純にポインタだったはずです。
逆に、
```
*a
```
みたいなのはポインタの指すメモリの実値を取得するやつだったはず。ChatGPTに聞いたら~~デシリアライズ~~デリファレンスていうらしい。

## てことは？
```
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_28とlocal_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)
```
みたいな感じであらわせるわけですね

## まとめ
ポインタの復習をしました。もうGhidra君の出してくるコードもこわくないね

## 追記
2023/12/26 一部誤りを修正
