此文推荐用于理解易语言(EPL)程序(EPP)的启动过程
首先,EPP可以有附加数据也可以没有,这个我想应该是取决于是不是独立编译这个选项的问题。
然后我们用OD载入一个EPP来看。区段一共5个,其中EPL被编译之后的代码储存于第二个.data区段。
不过听说以前这个区段叫做.ecode的,后来大该是因为EcE的出现而被和谐了,所以我们需要一个定心丸:
00403861 > 55 push ebp <-这个是exe的oep
00403862 8BEC mov ebp, esp
00403864 6A FF push -1
00403866 68 F0624000 push 004062F0
0040386B 68 D44C4000 push 00404CD4
00403870 64:A1 00000000 mov eax, dword ptr fs:[0]
00403876 50 push eax
...
0040391D 50 push eax
0040391E FF75 9C push dword ptr [ebp-64]
00403921 56 push esi
00403922 56 push esi
00403923 FF15 3C604000 call dword ptr [<&KERNEL32.GetModuleH>; kernel32.GetModuleHandleA
00403929 50 push eax
0040392A E8 0BD8FFFF call 0040113A <-WinMain
0040113A 55 push ebp <-WinMain
0040113B 8BEC mov ebp, esp
0040113D 81EC 98020000 sub esp, 298
00401143 53 push ebx
...Keep going, going, going, and going...
00401480 8D85 68FDFFFF lea eax, dword ptr [ebp-298]
00401486 50 push eax
00401487 FF15 04604000 call dword ptr [<&KERNEL32.LoadLibrar>; kernel32.LoadLibraryA
0040148D 3BC3 cmp eax, ebx
0040148F 75 09 jnz short 0040149A
00401491 C745 FC 00714000 mov dword ptr [ebp-4], 00407100 ; ASCII "Failed to load kernel library!"
00401498 EB 52 jmp short 004014EC
0040149A 68 F4704000 push 004070F4 ; ASCII "GetNewSock"
0040149F 50 push eax
004014A0 FF15 00604000 call dword ptr [<&KERNEL32.GetProcAdd>; kernel32.GetProcAddress
004014A6 3BC3 cmp eax, ebx ;这一段做标记应该很好找的。。
...稍微再下面一点...
004014FA 395D FC cmp dword ptr [ebp-4], ebx
004014FD 75 13 jnz short 00401512
004014FF 8B45 F0 mov eax, dword ptr [ebp-10]
00401502 E8 00000000 call 00401507
00401507 810424 F97A0000 add dword ptr [esp], 7AF9 <-这里加法做完就是EPP的代码基址了
0040150E FFD0 call eax <-听说过有内存载入DLL的代码么?这里就有EPP的定制版。。
这里我们得到的EPP基址为0x409000。然后我们来看这段内存:
00409000 00004A57 WJ.. <-我是用EPL开发的,所以我要有WJ标记,恩恩...
00409004 00000000 ....
00409008 00000000 ....
0040900C 00000000 ....
00409010 00000000 ....
00409014 00000000 ....
00409018 00000000 ....
0040901C 00000000 ....
00409020 00000000 ....
00409024 00000279 y..
00409028 00000001 ...
0040902C 00000003 ...
00409030 00000000 ....
00409034 00010123 #.
00409038 00000000 ....
0040903C 00197A26 &z. <-EPP的OEP偏移,那实际OEP就是0x197A26+0x409000=0x5a0a26
00409040 00000279 y.. <-const,常量表的offset
00409044 000DDFD4 赃.. <-form,窗体描述的offset
00409048 00192B52 R+. <-help,EPL_API的填充内存
0040904C 00192BBE ?. <-code,代码段中需要填充的数据的描述表,就是把上面的3个表中每一项的地址写入代码中对应的地方。比如:push const1, call [epp_api2]之类的。
00409050 00197AA3 . <-var,变量描述表
其实这后面还有一行,不过和const表的偏移一样,猜测是reloc表的,但是Exe是不需要reloc的。所以随便了一下?
前面么也照例还有一快空地,这里写着导入的EPP的支持库
直接OD内存复制了,就不开IDA了。有点乱码,见谅见谅...
00409050 6B 72 6E 6C 6E 0D 64 30 krnln.d0
00409060 39 66 32 33 34 30 38 31 38 35 31 31 64 33 39 36 9f2340818511d396
00409070 66 36 61 61 66 38 34 34 63 37 65 33 32 35 0D 34 f6aaf844c7e325.4
00409080 0D 36 0D CF B5 CD B3 BA CB D0 C4 D6 A7 B3 D6 BF .6.系统核心支持
00409090 E2 00 48 74 6D 6C 56 69 65 77 0D 35 30 31 34 44 ?HtmlView.5014D
004090A0 38 46 41 36 44 43 41 34 30 62 36 38 46 41 36 32 8FA6DCA40b68FA62
004090B0 36 44 38 31 38 33 36 36 36 45 42 0D 31 0D 31 0D 6D8183666EB.1.1.
004090C0 B3 AC CE C4 B1 BE E4 AF C0 C0 BF F2 D6 A7 B3 D6 超文本浏览框支持
004090D0 BF E2 00 69 65 78 74 32 0D 41 46 36 41 44 38 30 库.iext2.AF6AD80
004090E0 41 41 34 32 34 34 41 35 39 41 46 42 33 44 38 33 AA4244A59AFB3D83
004090F0 45 43 46 35 31 37 33 43 43 0D 31 0D 32 0D C0 A9 ECF5173CC.1.2.扩
00409100 D5 B9 BD E7 C3 E6 D6 A7 B3 D6 BF E2 B6 FE 00 69 展界面支持库二.i
00409110 65 78 74 0D 32 37 62 62 32 30 66 64 64 33 65 31 ext.27bb20fdd3e1
00409120 34 35 65 34 62 65 65 33 64 62 33 39 64 64 64 36 45e4bee3db39ddd6
00409130 65 36 34 63 0D 31 0D 36 0D C0 A9 D5 B9 BD E7 C3 e64c.1.6.扩展界
00409140 E6 D6 A7 B3 D6 BF E2 D2 BB 00 69 6E 74 65 72 6E 嬷С挚庖?intern
00409150 65 74 0D 37 30 37 63 61 33 37 33 32 32 34 37 34 et.707ca37322474
00409160 66 36 63 61 38 34 31 66 30 65 32 32 34 66 34 62 f6ca841f0e224f4b
00409170 36 32 30 0D 31 0D 31 0D BB A5 C1 AA CD F8 D6 A7 620.1.1.互联网支
00409180 B3 D6 BF E2 00 73 68 65 6C 6C 0D 35 32 46 32 36 持库.shell.52F26
00409190 30 30 32 33 30 35 39 34 35 34 31 38 37 41 46 38 0023059454187AF8
004091A0 32 36 41 33 43 30 37 41 46 32 41 0D 31 0D 30 0D 26A3C07AF2A.1.0.
004091B0 B2 D9 D7 F7 CF B5 CD B3 BD E7 C3 E6 B9 A6 C4 DC 操作系统界面功能
004091C0 D6 A7 B3 D6 BF E2 00 65 43 6F 6D 70 72 65 73 73 支持库.eCompress
004091D0 0D 37 42 36 38 37 33 36 45 38 31 38 45 34 31 63 .7B68736E818E41c
004091E0 35 41 32 38 42 30 41 45 34 44 34 33 43 31 32 38 5A28B0AE4D43C128
004091F0 43 0D 31 0D 31 0D D1 B9 CB F5 BD E2 D1 B9 D6 A7 C.1.1.压缩解压支
00409200 B3 D6 BF E2 00 65 41 50 49 0D 46 37 46 43 31 41 持库.eAPI.F7FC1A
00409210 45 34 35 43 35 43 34 37 35 38 41 46 30 33 45 46 E45C5C4758AF03EF
00409220 31 39 46 31 38 41 33 39 35 44 0D 31 0D 32 0D D3 19F18A395D.1.2.
00409230 A6 D3 C3 BD D3 BF DA D6 A7 B3 D6 BF E2 00 45 54 τ媒涌谥С挚?ET
00409240 68 72 65 61 64 0D 35 46 39 39 43 31 36 34 32 41 hread.5F99C1642A
00409250 32 46 34 65 30 33 38 35 30 37 32 31 42 34 46 35 2F4e03850721B4F5
00409260 44 37 43 33 46 38 0D 31 0D 31 0D B6 E0 CF DF B3 D7C3F8.1.1.多线
00409270 CC D6 A7 B3 D6 BF E2 00 讨С挚?.8..
常量表:
00409279 00000038 8... 表的描述部分大小0x38,不包括常量内容的大小
0040927D 000DDFD4 赃.. 下一个表的offset-这个表的offset=这个数值
00409281 00000001 ... 未知
00409285 736E6F63 cons 我是常量表...
00409289 00000074 t...
0040928D 00000000 ....
00409291 00000000 ....
00409295 00000000 ....
00409299 00000000 ....
0040929D 000DDD23 #?. 未知
004092A1 000DDD23 #?. 未知
004092A5 000002B1 ?.. 常量表加法基址,这个标记的意义将在code表中被说明
004092A9 00000000 .... 常量的数量
004092AD 00000000 .... 表描述结束标记
下面就是常量内容了,一般而言是遇到某个数字第二位是0就算是一个常量,不过也有特殊的,比如这个程序的常量里面包含了一个PE文件,大小是0xF400,这个常量就比较奇怪了,他的大小写在了自身本体的之前。所以常量的具体加载判定还是有些模糊。
窗体表就不看了吧,天知道他怎么描述的。。。
help表:
0059BB52 00000038 8... 意义同常量表
0059BB56 00192BBE ?. 意义同常量表
0059BB5A 00000001 ...
0059BB5E 706C6568 help 意义同常量表
0059BB62 00000000 ....
0059BB66 00000000 ....
0059BB6A 00000000 ....
0059BB6E 00000000 ....
0059BB72 00000000 ....
0059BB76 00000034 4...
0059BB7A 00000034 4...
0059BB7E 00192B8A ?. 意义同常量表
0059BB82 00000000 ....
0059BB86 00000000 ....
0059BB8A 00BD95A9 ? krnln.00BD95A9 以下就是程序中用到的EPP_API的地址
0059BB8E 00BD8DBF 繊? krnln.00BD8DBF
0059BB92 00BD8DCA 蕧? krnln.00BD8DCA
0059BB96 00BD8E21 !幗. krnln.00BD8E21
0059BB9A 00BD95C7 菚? krnln.00BD95C7
0059BB9E 00BD95E6 鏁? krnln.00BD95E6
0059BBA2 00BD9662 b柦. krnln.00BD9662
0059BBA6 00BD96BF 繓? krnln.00BD96BF
0059BBAA 00BD976A j椊. krnln.00BD976A
0059BBAE 00BD96A2 ? krnln.00BD96A2
0059BBB2 00BD960D .柦. krnln.00BD960D
0059BBB6 00BD9637 7柦. krnln.00BD9637
0059BBBA 00BD8DA5 ? krnln.00BD8DA5
code表:
0059BBBE 000007AC ?..
0059BBC2 00197AA3 .
0059BBC6 00000005 ...
0059BBCA 65646F63 code
0059BBCE 00000000 ....
0059BBD2 00000000 ....
0059BBD6 00000000 ....
0059BBDA 00000000 ....
0059BBDE 00000000 ....
0059BBE2 00004739 9G..
0059BBE6 00004739 9G..
0059BBEA 0019336A j3.
0059BBEE 000001DD ?..
0059BBF2 00000000 ....
0059BBF6 000006A1 ?..
0059BBFA 000006D2 ?..
0059BBFE 000006F9 ?..
0059BC02 00000811 ..
0059BC06 000009F1 ?..
0059BC0A 00000A59 Y...
0059BC0E 00001111 ..
0059BC12 00001142 B..
0059BC16 00001169 i..
......
这里来解释常量表加法基址,当然这边就是代码填充表加法基址了。
首先这边一共有0x1DD项,然后第一项的数据为0x6a1,那么
A=0x6a1/8=0xd4,
B=0x6a1 and 7 =1,
所以需要填充的数据的位置为[加法基址+A],填充的数据为第B个表的地址。
什么,你说常量表那么大,怎么区分哪个常量?这个么:
0059C43C db 0xB2
0059C43D 68 B1924000 push 004092B1
0059C442 FF35 B00C1901 push dword ptr [1190CB0]
0059C448 68 02000000 push 2
0059C44D B9 03000000 mov ecx, 3
0059C452 E8 7EFFFFFF call 0059C3D5
我猜就是这么决定的吧。至于具体的,我又没去逆代码...
最后飞向OEP吧:
00BD8CDE . E8 AD060300 call 00C09390 ;Proc_MemoryLoadEPP
00BD8CE3 .- FFE0 jmp eax ;OEP of EPP
收工,就知道这么多了,全倒出来了……
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!