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フォーマット)の構造にも興味が沸いてきました。



コメント