๋ฌธ์ : DreamHack โ patch ๋ถ๋ฅ: Reversing ๋์ด๋: ๐ฅ Silver 4 FLAG:
DH{UPATCHED}
๋ฌธ์ ์ด๋ฆ ๊ทธ๋๋ก "ํจ์น"๊ฐ ๋ต์ด๋ค. ์คํํ๋ฉด ์ฐฝ์ flag๋ฅผ ๊ทธ๋ ค ์ฃผ๋๋ฐ, ๊ฐ์ด๋ฐ๊ฐ ๊ฒ์ ๋ง๋๋ก ๋ฎ์ฌ ์๋ค. ์ ๋ ฅ๋ ๊ฒ์ฆ๋ ์๋ค. flag๋ฅผ ๊ทธ๋ฆฌ๋ ๋ฐฉ์์ ๋ฏ์ด๋ณด๊ณ , ๊ทธ ๊ทธ๋ฆผ์์ ๊ฐ๋ฆผ๋ง๋ง ๊ฑท์ด๋ด๋ฉด ๋๋ค.

๋ฌธ์ ๊ฐ์
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| ๋ฌธ์ ๋ช | patch |
| ๋์ด๋ | ๐ฅ Silver 4 |
| ๋ถ๋ฅ | Reversing |
| ๋์ | Patch.exe (PE32+ GUI, x86-64, GDI+) |
| ํต์ฌ | flag ๊ธ์๋ฅผ ๊ฒ์ ์ผ๋ก, ๊ทธ ์ ๊ฐ๋ฆผ๋ง๋ ๊ฒ์ ์ผ๋ก โ ๊ฒ์ ์ ๊ฒ์ ์ด๋ผ ์ ๋ณด์. ๊ฐ๋ฆผ๋ง ํจ์๋ฅผ ๋ฌด๋ ฅํ |
๋ฌธ์ ์ค๋ช ๋ ์น์ ํ๋ค โ "flag๋ฅผ ๊ทธ๋ฆฌ๋ ๋ฃจํด์ ๋ถ์ํ๊ณ ๊ฐ๋ ค์ง flag๋ฅผ ๋ณด์ด๊ฒ ํด ์ฃผ์ธ์"์, ์ฐธ๊ณ ๋งํฌ๋ก GDI+ ๋ฌธ์์ x64dbg์ Patch File ๊ธฐ๋ฅ์ ๊ฑธ์ด ๋๋ค. ๊ทธ๋ฆฌ๊ธฐ ๋ฃจํด์ ์ฝ๊ณ , ๋ฐ์ด๋๋ฆฌ๋ฅผ ํจ์นํ๋ผ๋ ๋ป์ด๋ค.
๐งฉ ๋ฐฐ๊ฒฝ โ GDI+ ๋ผ์ธ ๋๋ก์
์ด ํ๋ก๊ทธ๋จ์ ํ
์คํธ ์ถ๋ ฅ API(TextOutยทDrawText)๋ฅผ ์ฐ์ง ์๋๋ค. ๋์ GDI+์ ์ ๊ทธ๋ฆฌ๊ธฐ๋ก ๊ธ์ ํ๋ํ๋๋ฅผ ์ง์ ๊ทธ๋ฆฐ๋ค. import๋ฅผ ๋ณด๋ฉด ์ฐ๋ ํจ์๊ฐ ๋ช ๊ฐ ์ ๋๋ค.
GdiplusStartup / GdipCreateFromHDC ; GDI+ ์์, HDC๋ก Graphics ์์ฑ
GdipCreatePen1(ARGB color, REAL width, Unit, Pen**) ; ์ยท๋๊ป๋ฅผ ๊ฐ์ง ํ
GdipDrawLineI(Graphics, Pen, x1, y1, x2, y2) ; ๋ ์ ์ ์๋ ์
GdipSetSmoothingMode / GdipDeletePen / GdipDeleteGraphicsGdipCreatePen1์ ์ฒซ ์ธ์๊ฐ ํ ์(ARGB, ์: 0xff000000 = ๋ถํฌ๋ช
๊ฒ์ )์ด๊ณ , GdipDrawLineI๊ฐ ๊ทธ ํ์ผ๋ก ์ ์ ๊ธ๋๋ค. ์ฆ ํ๋ฉด์ ๋ชจ๋ ๊ฒ์ด ์ ๋ถ์ ๋ชจ์์ด๋ค. flag ๊ธ์๋, ๊ทธ๊ฑธ ๊ฐ๋ฆฌ๋ ๋ง๋๋ ์ ๋ถ ์ ์ผ๋ก ๊ทธ๋ ค์ง๋ค. ๊ทธ๋์ "๋ฌด์จ ์ ์ ์, ์ด๋ค ์์๋ก ๊ธ๋๊ฐ"๊ฐ ์ด ๋ฌธ์ ์ ์ ๋ถ๋ค.
๐ฌ ์ ์ฐฐ โ ๋๊ฐ ๋ฌด์์ ๊ทธ๋ฆฌ๋
strings๋ก๋ flag๊ฐ ์ ๋์จ๋ค(๊ธ์๊ฐ ๋ฌธ์์ด์ด ์๋๋ผ ์ ๋ถ ์ขํ๋ก ๋ฐํ ์์ผ๋ ๋น์ฐํ๋ค). import๋ง GDI+๋ก ๊ฐ๋ํ๋ค.

GdipDrawLineI ํธ์ถ์ฒ๋ฅผ ๋ฐ๋ผ๊ฐ๋ฉด ํจ์๊ฐ ์๋ฉ ๋์จ๋ค. ๊ธ์ ํ ์๋น ํจ์ ํ๋๊ผด๋ก, ๊ฐ ํจ์๊ฐ GdipCreatePen1(์์ ์ธ์๋ก ๋ฐ์) โ GdipDrawLineI๋ฅผ ์ฌ๋ฌ ๋ฒ ๋ฐ๋ณตํด ๊ธ์ ๋ชจ์์ ๋ง๋ ๋ค. ์ด ๊ธ์ ํจ์๋ค์ ํ๋ฐ ๋ชจ์ ํธ์ถํ๋ ๊ณณ์ด ๊ทธ๋ฆฌ๊ธฐ ์ค์ผ์คํธ๋ ์ดํฐ(fcn.140002c40)๋ค.
์ค์ผ์คํธ๋ ์ดํฐ๋ ๋ ๋จ๊ณ๋ก ๋๋๋ค. ๋จผ์ fcn.140002b80์ x์ขํ 30, 35, 40 โฆ 90์ผ๋ก 25๋ฒ ๋ถ๋ฅด๊ณ , ๊ทธ ๋ค์ ๊ธ์ ํจ์ 12๊ฐ๋ฅผ ์ 0xff000000(๊ฒ์ )์ผ๋ก ๋ถ๋ฅธ๋ค.

์ฌ๊ธฐ์ ๋์ ๊ฑธ๋ฆฌ๋ ๊ฒ ๋ ๊ฐ์ง๋ค. โ ์์ชฝ fcn.140002b80๋ ํธ์ถํ ๋ ์คํ์ผ๋ก ์ 0xff000000(๊ฒ์ )์ ๋๊ธด๋ค. โก ๊ธ์ ํจ์๋ค๋ ์์ด 0xff000000(๊ฒ์ )์ด๋ค. ๋ ๋ค ๊ฒ์ ์ธ๋ฐ, ํ๋๋ ๋จผ์ ๊ทธ๋ ค์ง๋ค.
๐ฃ ํต์ฌ โ ๊ฒ์ ๊ฐ๋ฆผ๋ง ์์ ๊ฒ์ ๊ธ์
fcn.140002b80์ด ๋ฌด์์ ๊ทธ๋ฆฌ๋์ง ๋ณด๋ฉด ๋ต์ด ๋์จ๋ค. ํ ๋๊ป๊ฐ 10.0(์์ 0x41200000)์ผ๋ก ๊ธ์์ฉ ํ(๋๊ป 4)๋ณด๋ค ํจ์ฌ ๊ตต๊ณ , ํธ์ถ๋ ๋๋ง๋ค x๋ฅผ 5์ฉ ์ฎ๊ฒจ ๊ฐ๋ฉฐ ์ ์ ๊ธ๋๋ค. ๊ตต์ ์ 25๊ฐ๋ฅผ ์ด์ดํ ๊ฒน์น๋ฉด โ ์์ด ๊ฝ ์ฐฌ ๊ฒ์ ์ฌ๊ฐํ, ์ฆ ๊ฐ๋ฆผ๋ง์ด ๋๋ค.

๊ทธ๋ฆฌ๋ ์์๊ฐ ํจ์ ์ด๋ค.
- ๋จผ์ ๊ฐ๋ฆผ๋ง(๊ฒ์ ์ฌ๊ฐํ)์ flag ๊ฐ์ด๋ฐ ์์น์ ๊ทธ๋ฆฐ๋ค.
- ๊ทธ ๋ค์ flag ๊ธ์๋ค์ ๊ฒ์ ์ผ๋ก ๊ทธ ์์ ๊ทธ๋ฆฐ๋ค.
GDI+๋ ๋ถ๋ฅธ ์์๋๋ก ์์ ๋ง์น ํ๋ฏ๋ก, ๊ฐ์ด๋ฐ ๊ธ์๋ค์ ๊ฐ๋ฆผ๋ง ์์ ๊ทธ๋ ค์ง๋ค. ๊ทธ๋ฐ๋ฐ ๊ธ์๋ ๊ฒ์ , ๊ฐ๋ฆผ๋ง๋ ๊ฒ์ ์ด๋ผ ๊ฒ์ ์ ๊ฒ์ = ๊ตฌ๋ถ ๋ถ๊ฐ๋ค. ๋ฐ๋ฉด DH{์ }๋ ๊ฐ๋ฆผ๋ง ๋ฐ๊นฅ(ํฐ ๋ฐฐ๊ฒฝ) ์์น๋ผ ๊ฒ์ ๊ธ์๊ฐ ๋ฉ์ฉกํ ๋ณด์ธ๋ค. flag๊ฐ "์ํธํ"๋ ๊ฒ ์๋๋ผ, ๋ง ๊ทธ๋๋ก ๊ฐ์ ์์ผ๋ก ๋ง์น ํด ๊ฐ๋ ค ๋ ๊ฒ์ด๋ค.

ํด๊ฒฐ์ฑ
์ ๊ฐ๋ฆผ๋ง์ ์์ ๋ ๊ฒ ํ๋๋ก ์ถฉ๋ถํ๋ค. ๊ฐ๋ฆผ๋ง์ ๊ทธ๋ฆฌ๋ ํจ์ fcn.140002b80์ด ์๋ฌด๊ฒ๋ ์ ํ๊ฒ ๋ง๋ค๋ฉด, ๊ฐ์ด๋ฐ ๊ฒ์ ๊ธ์๋ค์ด ํฐ ๋ฐฐ๊ฒฝ ์์ ๊ทธ๋๋ก ๋จ๋๋ค.
โถ๐ ์ฝ์ง โ ์ ๋ ฅยท๋ฌธ์์ดยท์ต์ค๋ถํฐ ๋ค์ก๋ค
๋ฆฌ๋ฒ์ฑ์ด๋ผ ๋ฐ์ฌ์ ์ผ๋ก strings๋ถํฐ ๋๋ ธ๋ค. flag ๋น์ทํ ๊ฒ๋, "Correct/Wrong" ๊ฐ์ ๋ถ๊ธฐ ๋ฌธ์์ด๋ ์๋ค. ์
๋ ฅ์ ๋ฐ๋ ์ฝ๋(GetWindowTextยทscanf ๋ฑ)๋ ์๋ค โ ์ ์ด์ ์ฌ์ฉ์ ์
๋ ฅ์ผ๋ก ๋ญ ๋งํ๋ ๋ฌธ์ ๊ฐ ์๋์๋ค.
๊ทธ ๋ค์์ "์ด๋๊ฐ flag๋ฅผ ์กฐ๋ฆฝํ๋ ๋ฃจํด์ด ์๊ฒ ์ง" ํ๊ณ mainโWinMain์ ๋ฐ๋ผ๊ฐ๋๋ฐ, ๋์ค๋ ๊ฑด RegisterClassExW๋ก ์ฐฝ ํ๋ ๋ง๋ค๊ณ WM_PAINT์์ ๊ทธ๋ฆผ์ ๊ทธ๋ฆฌ๋ ํ๋ฒํ GUI ๊ณจ๊ฒฉ๋ฟ์ด์๋ค. ๊ฒฐ๊ตญ "์ด๊ฑด ์
๋ ฅ์ ํธ๋ ๊ฒ ์๋๋ผ ๊ทธ๋ฆผ์ ํธ๋ ๋ฌธ์ "๋ผ๋ ๊ฑธ ๋ฐ์๋ค์ด๊ณ ๋์์ผ GDI+ ํธ์ถ๋ค๊ณผ ๊ทธ๋ฆฌ๊ธฐ ์์๊ฐ ๋์ ๋ค์ด์๋ค. ๋ฌธ์ ์ค๋ช
์ "flag๋ฅผ ๊ทธ๋ฆฌ๋ ๋ฃจํด"์ด๋ผ๋ ํํ์ด ์ ํํ ํํธ์๋ค.
๐ฏ ํจ์น โ ๊ฐ๋ฆผ๋ง ํจ์๋ฅผ ret ์ํค๊ธฐ
fcn.140002b80์ ๊ฐ๋ฆผ๋ง๋ง ๊ทธ๋ฆฐ๋ค. ๊ทธ๋ฌ๋ ์ด ํจ์์ ์ฒซ ๋ช
๋ น์ ret(0xC3)๋ก ๋ฐ๊พธ๋ฉด, ํธ์ถ๋ผ๋ ์ฆ์ ๋์๊ฐ ์๋ฌด๊ฒ๋ ์ ๊ทธ๋ฆฐ๋ค. ํจ์ ์ง์
์งํ๋ผ ์คํ์ pushํ ๊ฒ๋ ์์ด ๊ทธ๋ฅ ret ํ ๋ฐ์ดํธ๋ฉด ๊น๋ํ๋ค.
ํจ์ ์์์ ๊ฐ์์ฃผ์ 0x140002b80์ด๊ณ , .text ์น์
์ด ๊ฐ์์ฃผ์ 0x140001000 โ ํ์ผ ์คํ์
0x400์ ๋งคํ๋๋ ํ์ผ ์คํ์
์ 0x140002b80 - 0x140001000 + 0x400 = 0x1f80์ด๋ค. ๊ทธ ์๋ฆฌ์ 0x48(ํ๋กค๋ก๊ทธ ์ฒซ ๋ฐ์ดํธ)์ 0xC3์ผ๋ก ๋ฎ๋๋ค. x64dbg๋ผ๋ฉด ๊ทธ ์ฃผ์์์ Assemble โ ret ํ Patch File์ ํ๋ฉด ๋๊ณ , ์ฌ๊ธฐ์ ๊ฐ์ ์ผ์ ํ์ผ์ ์ง์ ํ๋ค.
# patch.py
COVER_VA = 0x140002b80
TEXT_VA = 0x140001000 # .text ๊ฐ์์ฃผ์
TEXT_PADDR = 0x400 # .text ํ์ผ์คํ์
off = COVER_VA - TEXT_VA + TEXT_PADDR # 0x1f80
data = bytearray(open("Patch.exe", "rb").read())
assert data[off] == 0x48
data[off] = 0xC3 # ๊ฐ๋ฆผ๋ง ํจ์๋ฅผ ์ฆ์ ret
open("Patch_patched.exe", "wb").write(data)
ํจ์นํ ์คํ ํ์ผ์ (์ฌ๊ธฐ์๋ wine๋ก) ์คํํ๋ฉด ๊ฐ๋ฆผ๋ง์ด ์ฌ๋ผ์ง๊ณ ๊ฐ์ด๋ฐ ๊ธ์๊ฐ ํฐ ๋ฐฐ๊ฒฝ ์์ ๋๋ฌ๋๋ค.

์ธ๊ทธ๋จผํธ ํฐํธ๋ผ ๊ธ์๊ฐ ๊ฐ์ ธ ๋ณด์ด์ง๋ง ๊ทธ๋๋ก ์ฝํ๋ค โ D H { U P A T C H E D }.
DH{UPATCHED}๊ฐ๋ฆผ๋ง์ ์๋ง ํฐ์์ผ๋ก ๋ฐ๊พธ๊ฑฐ๋(ํธ์ถ์ฒ 25๊ณณ์ 0xff000000 โ 0xffffffff), ๊ธ์ ์์ ๊ฒ์ ์ด ์๋ ์์ผ๋ก ๋ฐ๊ฟ๋ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋์ค์ง๋ง, ๊ฐ๋ฆผ๋ง ํจ์ ํ๋๋ฅผ ret ์ํค๋ 1๋ฐ์ดํธ ํจ์น๊ฐ ๊ฐ์ฅ ๊ฐ๋จํ๋ค.
๐ ๊ฒฐ๋ก
๋ณด์ด์ง ์๋๋ค๊ณ ์๋ ๊ฒ ์๋๋ค. ์ด ๋ฌธ์ ์ flag๋ ์ํธํ๋๊ฑฐ๋ ์ด๋๊ฐ ์จ๊ฒจ์ง ๊ฒ ์๋๋ผ, ํ๋ฉด์ ๋ฉ์ฉกํ ๊ทธ๋ ค์ง ๋ค ๊ฐ์ ์์ผ๋ก ํ ๋ฒ ๋ ๋ง์น ํด ์๊ฐ์ ์ผ๋ก๋ง ๊ฐ๋ ค์ ธ ์์๋ค. ๋ฐ์ดํฐ๋ ์ฒ์๋ถํฐ ๊ฑฐ๊ธฐ ์์๊ณ , ๊ทธ๊ฒ์ ๊ฐ๋ฆฐ ๊ฒ๋ ์ฝ๋ ๋ช ์ค์ด๋ค. ๊ทธ๋ฆฌ๋ ์์(z-order)์ ์๋ง ๋ฐ๊พธ๋ฉด ๊ทธ๋๋ก ๋๋ฌ๋๋ค.
์ ๋ฆฌํ๋ฉด,
- "๊ฐ๋ฆผ = ๋ณดํธ"๊ฐ ์๋๋ค. UI์์ ๋ฌด์ธ๊ฐ๋ฅผ ๊ฒ์ ์ฌ๊ฐํยท๋ธ๋ฌยท
visibility:hidden์ผ๋ก ๋ฎ์ด๋, ๊ทธ ์๋ ์๋ณธ ๋ฐ์ดํฐ๋ ๊ทธ๋๋ก ์กด์ฌํ๋ค. ๋ฏผ๊ฐ ์ ๋ณด๋ ๋ ๋๋ง ๋จ๊ณ๊ฐ ์๋๋ผ ๋ฐ์ดํฐ ๋จ๊ณ์์ ๋นผ์ผ ํ๋ค(์๋ฒ์์ ๋ง์คํนํด ๋ด๋ ค๋ณด๋ด๊ธฐ ๋ฑ). - ๋ฐ์ด๋๋ฆฌ ํจ์น์ ๊ธฐ๋ณธ๊ธฐ. ๋ถ๊ธฐ ํ๋, ํจ์ ํ๋๋ฅผ
ret/nop์ผ๋ก ๋ฐ๊พธ๋ ๊ฒ๋ง์ผ๋ก ํ๋ก๊ทธ๋จ์ ํ๋์ ํต์งธ๋ก ๋ฐ๊ฟ ์ ์๋ค. ๋ผ์ด์ ์ค ์ฒดํฌยท์ํฐ๋๋ฒ๊น ์ฐํ ๊ฐ์ ์ค์ ๋ถ์๋ ๊ฐ์ ์๋ฆฌ์ด๊ณ , x64dbg์ Patch File์ด ์ ํํ ์ด ์์ ์ GUI๋ก ํด ์ค๋ค. - ๊ทธ๋ฆผ๋ ์ฝ๋๋ค. ์ถ๋ ฅ์ด ํ
์คํธ๊ฐ ์๋๋ผ ๊ทธ๋ํฝ์ด๋ฉด
strings๋ก๋ ์ ์กํ๋ค. ๋ฌด์์ ๊ทธ๋ฆฌ๋ API์ธ์ง(GDI/GDI+/Direct2Dโฆ)๋ถํฐ ์๋ณํ๊ณ , ๊ทธ ํธ์ถ ์์์ ์ธ์(์ยท์ขํ)๋ฅผ ๋ฐ๋ผ๊ฐ๋ฉด "๊ทธ๋ฆผ์ผ๋ก ์จ๊ธด ๊ฐ"๋ ๊ฒฐ๊ตญ ์ฝ์ด๋ผ ์ ์๋ค.
Comments
๋๊ธ
๋๊ธ์ ๋จ๊ธฐ๋ ค๋ฉด ๋ก๊ทธ์ธ์ด ํ์ํด์. (๋ค์ด๋ฒ ยท ๊ตฌ๊ธ ๊ณ์ )
๋๊ธ ๋ถ๋ฌ์ค๋ ์คโฆ