Delphi入口程序
Delphi开头的入口程序是正常的压栈,然后调用一个E8字节类型的call
0044CA98 > $ 55 push ebp
0044CA99 . 8BEC mov ebp,esp
0044CA9B . 83C4 F0 add esp,-0x10
0044CA9E . B8 B8C84400 mov eax,delphi7?0044C8B8 ; UNICODE “;”
0044CAA3 . E8 2091FBFF call delphi7?00405BC8
E8字节Call中的内容调用了一个GetModuleHandleA()函数
00405BC8 /$ 53 push ebx
00405BC9 |. 8BD8 mov ebx,eax ; delphi7?0044C8B8
00405BCB |. 33C0 xor eax,eax ; delphi7?0044C8B8
00405BCD |. A3 9CD04400 mov dword ptr ds:[0x44D09C],eax ; delphi7?0044C8B8
00405BD2 |. 6A 00 push 0x0 ; /pModule = NULL
00405BD4 |. E8 2BFFFFFF call <jmp.&kernel32.GetModuleHandleA> ; \GetModuleHandleA
进入这个系统dll调用,发现一个跳转jmp的字节码对应是 FF25
00405B04 $- FF25 E4014500 jmp dword ptr ds:[<&kernel32.GetModuleHa>; kernel32.GetModuleHandleA
我们可以识别这些机器码和调用的函数来判断是否进入了程序的入口点。
BC++入口程序
入口点是一个jmp,jmp中间是语段字符fb:C++HOOK,之后的第一个调用是GetModuleHandleA()函数
0040135C > $ /EB 10 jmp short BC2002例.0040136E
0040135E |66 db 66 ; CHAR ‘f’
0040135F |62 db 62 ; CHAR ‘b’
00401360 |3A db 3A ; CHAR ‘:’
00401361 |43 db 43 ; CHAR ‘C’
00401362 |2B db 2B ; CHAR ‘+’
00401363 |2B db 2B ; CHAR ‘+’
00401364 |48 db 48 ; CHAR ‘H’
00401365 |4F db 4F ; CHAR ‘O’
00401366 |4F db 4F ; CHAR ‘O’
00401367 |4B db 4B ; CHAR ‘K’
00401368 |90 nop
00401369 |E9 db E9
0040136A . |98904700 dd BC2002例.___CPPdebugHook
0040136E > \A1 8B904700 mov eax,dword ptr ds:[0x47908B]
00401373 . C1E0 02 shl eax,0x2
00401376 . A3 8F904700 mov dword ptr ds:[0x47908F],eax
0040137B . 52 push edx ; ntdll.KiFastSystemCallRet
0040137C . 6A 00 push 0x0 ; /pModule = NULL
0040137E . E8 83640700 call <jmp.&KERNEL32.GetModuleHandleA> ; \GetModuleHandleA
GetModuleHandleA这个系统API也是FF25的间接跳转实现
00477806 $- FF25 E0824800 jmp dword ptr ds:[<&KERNEL32.GetModuleHa>; kernel32.GetModuleHandleA
VC入口特征
004183D7 >/$ 55 push ebp
004183D8 |. 8BEC mov ebp,esp
004183DA |. 6A FF push -0x1
004183DC |. 68 18CB4100 push VC.0041CB18
004183E1 |. 68 2C9D4100 push VC.00419D2C ; SE 处理程序安装
004183E6 |. 64:A1 0000000>mov eax,dword ptr fs:[0]
004183EC |. 50 push eax
004183ED |. 64:8925 00000>mov dword ptr fs:[0],esp
004183F4 |. 83EC 58 sub esp,0x58
004183F7 |. 53 push ebx
004183F8 |. 56 push esi
004183F9 |. 57 push edi
004183FA |. 8965 E8 mov [local.6],esp
004183FD |. FF15 74B14100 call dword ptr ds:[<&KERNEL32.GetVersion>; kernel32.GetVersion
发现VC的Call用的是FF15,而且VC入口点特征第一个调用函数是GetVersion()
VB程序入口特征
一进入VB程序,发现入口点定位在0x004014B0位置,该位置push了入口地址,上面还有个关于ThunRTMain的跳转,下面是ThunRTMain()函数调用,使用E8来进行函数调用。
入口点的push就是push了一段字符串的地址
004014AA $- FF25 F0104000 jmp dword ptr ds:[<&MSVBVM60.#ThunRTMain>; msvbvm60.ThunRTMain
004014B0 > $ 68 28264000 push vb例子.00402628
004014B5 . E8 F0FFFFFF call <jmp.&MSVBVM60.#ThunRTMain_100>
我们立即数跟随,发现push的是一段字符串,是一个dll的名字,我们可以通过搜索push该段字符串的地址的指令找到入口点,00402628 56 42 35 21 F0 1F 76 62 36 63 68 73 2E 64 6C 6C VB5!?vb6chs.dll
查找内容vb5!
alt+m打开内存窗口,然后ctrl+b输入vb5!。定位到0x402628
删除分析
可以直接搜索push指令的机器码:68 28 26 40 00,注意68push的是个立即数,不用进行偏移差计算。
将数据搜索到的地址进行反汇编查看
发现正好是我们要找的入口点
我们可以定位入口点上下调用的函数来定位入口点