TVアニメ「ヨルムンガンド」PV第1弾
アニメ『ヨルムンガルド』(2012)
最近ガンアクションに飢えており、既に見たアニメですがまた見てます。やはり内容を忘れてしまっているので結構楽めるし、ガンアクションにも満足です。
「a.outを編集してprintfの出力を変更する」で、a.out(ELF)を直接書き換えて出力文字列を変更しましたが、WindowsのEXEファイル(PEフォーマット)も同じようなことができるでしょうか。
C#のコンパイラcscで生成したファイルを確認してみます。
使うソースはこれです。
C:\Users\takk\tmp>type t.cs class Test { static void Main() { System.Console.WriteLine("HELLO"); } } C:\Users\takk\tmp>
C:\Users\takk\tmp>csc t.cs 省略 C:\Users\takk\tmp>
では、生成されたt.exeを、Linuxで確認。
takk@deb9:~/tmp$ ls -l t.exe -rw-r--r-- 1 takk takk 3584 8月 16 17:12 t.exe takk@deb9:~/tmp$
EXEファイルの先頭にはマジックナンバーMZが埋め込まれています。
takk@deb9:~/tmp$ hd t.exe | head 00000000 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 |MZ..............| 00000010 b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 |........@.......| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000030 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 |................| 00000040 0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 |........!..L.!Th| 00000050 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f |is program canno| 00000060 74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20 |t be run in DOS | 00000070 6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00 |mode....$.......| 00000080 50 45 00 00 4c 01 03 00 f5 31 75 5b 00 00 00 00 |PE..L....1u[....| 00000090 00 00 00 00 e0 00 02 01 0b 01 0b 00 00 04 00 00 |................| takk@deb9:~/tmp$
EXEファイル中の文字列を確認します。
takk@deb9:~/tmp$ strings t.exe -td 77 !This program cannot be run in DOS mode. 376 .text 415 `.rsrc 455 @.reloc 616 BSJB 632 v4.0.30319 668 #Strings 700 #GUID 716 #Blob 953 <Module> 962 t.exe 968 Test 973 mscorlib 982 System 989 Object 996 Main 1001 .ctor 1007 System.Runtime.CompilerServices 1039 CompilationRelaxationsAttribute 1071 RuntimeCompatibilityAttribute 1103 Console 1111 WriteLine 1201 WrapNonExceptionThrows 1282 _CorExeMain 1294 mscoree.dll 2259 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 2316 <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 2391 <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> 2457 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> 2513 <security> 2529 <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> 2599 <requestedExecutionLevel level="asInvoker" uiAccess="false"/> 2670 </requestedPrivileges> 2700 </security> 2717 </trustInfo> 2733 </assembly> takk@deb9:~/tmp$
HELLOがどこにもありません。プログラム中の文字列は、そのままバイナリになるわけではないようです。
念のため、grepで確認。
takk@deb9:~/tmp$ !! | grep HELLO strings t.exe -td | grep HELLO takk@deb9:~/tmp$
やはりありません。ということは、EXEファイルを書き換えて、文字列変更することはできない、ということになります。
EXEファイル中のその他のデータを書き換えることはできるでしょうか。
さきほどのstringsの一覧でファイル名らしきデータがありました。ファイル名なら書き換えても動作するかと思います。
962 t.exe
EXEファイルに埋め込まれているt.exeをu.exeに変更してみます。
takk@deb9:~/tmp$ cp t.exe u.exe takk@deb9:~/tmp$ echo u | dd seek=962 bs=1 count=1 conv=notrunc of=u.exe 1+0 レコード入力 1+0 レコード出力 1 byte copied, 0.000325551 s, 3.1 kB/s takk@deb9:~/tmp$
差分確認。
takk@deb9:~/tmp$ cmp -l t.exe u.exe 963 164 165 takk@deb9:~/tmp$
正しく変更されたようです。
では、Windowsにもどって、データを書き換えたEXEファイルが実行できるか確認してみます。
C:\Users\takk\tmp>u HELLO C:\Users\takk\tmp>
実行できました。
ELFだけでなくEXEファイル(PEフォーマット)の構造にも興味が沸いてきました。
コメント