非手続き型言語の生成するコードとは

昨日の最後のプログラム、リソースをテキストでべた打ちしながら
これはまともなアプリケーションなら書き換えられんように
しなければならないなぁ、そんなもん簡単な暗号化でも施しといたらいいやん?
でもそれだと逆アセしたら簡単に解析されてしまうんじゃ…。
あれ、ちょっと待てよ。Haskellのコードって逆アセして普通に
処理が追えるようなものなのか?遅延評価だぞ、遅延評価。
というか、そもそも処理も記述しないしな。


もしかしたらお手軽に破られにくい軽量な暗号が実現するかも、
ということで、調べてみることにした。

module Main(main) where

import System
import System.IO
import Data.Char
import Data.Bits

main = do
  [mode,infile] <- getArgs
  case mode of
    "-d"      -> p infile ".dec" decr
    "-e"      -> p infile ".enc" encr
    _ -> error "unknown option"
  where
    p infile ext f = do
      let outfile = takeWhile (/='.') infile ++ ext
      ih  <- openBinaryFile infile  ReadMode
      oh  <- openBinaryFile outfile WriteMode
      dat <- hGetContents ih
      hPutStr oh $ f dat

encr xs = map chr ps where
  ns = map ord xs
  ps = [(a `xor` b) `xor` 0x55 | (a,b) <- zip (0:ns) ns]

decr xs = map chr $ n:f (n:ns) where
  (n:ns) = map ((xor 0x55) . ord) xs
  f [_]        = []
  f (x:y:rest) = d:f (d:rest) where
    d = x `xor` y

適当に暗号・複合プログラムをでっち上げた。
encrが符号化・decrが復号化である。
アルゴリズムは隣り合うバイト同士のxorをとって
それから55hをxorするだけの簡単なもの。


これをGHCを用いてアセンブリリストにコンパイルしてみた。
で、読んでみようと思ったのだが、案の定というか、
思った通りというか、全然読めない。

.text
  .align 2
  .long  _r1fH_srt+16
  .long  131072
  .long	851986
 _s1ht_info:
.text
 _s1ht_entry:
/APP
/NO_APP
  leal  -20(%ebp), %eax
  cmpl  84(%ebx), %eax
  jb    L45
  addl  $12, %edi
  cmpl  92(%ebx), %edi
  jbe   L44
L45:
  movl  $3, 108(%ebx)
  jmp   *-8(%ebx)
L44:
  leal  -8(%ebp), %eax
  movl  $_stg_upd_frame_info, (%eax)
  movl  %esi, 4(%eax)
  movl  $_s1hr_info, -8(%edi)
  movl  $_GHCziBase_ord_closure, -12(%ebp)
  leal  -8(%edi), %eax
  movl  %eax, -16(%ebp)
  movl  $_GHCziBase_zi_closure, %esi
  subl  $20, %ebp
  jmp _stg_ap_pp_ret

適当な抜粋。全体では2000行ぐらいあるけど。

  movl  $_GHCziBase_ord_closure, -12(%ebp)

この辺にordを使ったかな、という痕跡が見て取れる。
がしかし、やっぱり全く読めない。
ソースのどことどこが対応しているのかさえ分からない。
しかも上のアセンブリソース、実際に実行ファイルから
アセンブラした場合はラベルが無いわけで、この程度も読み取れるかどうか。


結局今のところの感想としては
「解読無理っぽい」
そこで、今回は読者(居るんかいな?)への挑戦を残しておく。
符号・復号プログラムからアルゴリズムを推測して欲しい。
アルゴリズムが分かった方はコメントあたりでお知らせ願いたい。
プログラムは上のソースのencrとdecrを書き換えただけのもの。
アルゴリズムのレベルも大体上と同じぐらい。
正解者先着一名様には………何もありません。
私の考えの浅はかさが露呈するだけ…。

http://fxp.infoseek.ne.jp/haskell/encr.zip