各位大侠见笑了,本人第一次写篇掘文,就当是小菜一碟。敬请指教!

FLVPlayer播放器是一款免费的绿色*.flv视频播放器,界面十分简洁,但它却不能靠双击文件名来播放flv视频。双击文件名只能打开FLVPlayer播放器,然后拖曳文件到窗口或按下文件按钮选择要打开的文件,显得操作重复且不方便。为此将它作了如下改造就可以直接双击文件名播放了。
  改造思路:
1.  将文件的.text区段属性改为可读可写(C0000020),利用它的空余字节写代码;
2.  截获GetCommandLineA函数返回的字串,取出文件名和路径;
3.  将获取的文件名,模拟GetOpenFileNameA函数存入相应的数据结构(在堆栈)中;
4.  截获含有主窗口句柄的代码过程,取出句柄并建立一个新线程;
5.  新线程运行时,发出模拟鼠标动作的消息。

具体改造如下:(用16进制编辑器打开FLVPlayer.exe,只须将相应的代码键入即可)
1.  将文件的.text区段属性改为可读可写:
原    00000208:66 60    改为     00 6E     (增加代码区段长度)
原    00000227:60      改为     C0       (改属性为可读可写)

2.  截获GetCommandLineA函数返回的字串,取出文件名和路径:
原    00056331:A3 E0 78 48    改为   E8 52 0D 01  (运行到00067088添加的代码)
00067088——0006708F是添加的获取文件名地址的过程:(程序中的反汇编如下):

00467088     60_________________pushad
00467089      A3 E0784800________mov    [4878E0], eax
0046708E      50_________________push      eax 
0046708F      FF15 30824600______call      [<&KERNEL32.lstrlenA>] 
00467095      BB F0704600________mov       ebx, 004670F0
0046709A      8B15 E0784800______mov       edx, [4878E0]
004670A0      40_________________inc      eax
004670A1      50_________________push      eax
004670A2      52_________________push      edx
004670A3      53_________________push      ebx
004670A4     FF15 80804600______call      [<&KERNEL32.lstrcpynA>]
004670AA     BE F0704600________mov       esi, 004670F0
004670AF      8A06______________mov       al, [esi]
004670B1      84C0______________test      al, al
004670B3      74 23______________je        short 004670D8
004670B5      46________________inc       esi
004670B6     8A06______________mov       al, [esi]
004670B8    3C 22______________cmp       al, 22
004670BA     75 F9  ______________jnz       short 004670B5
004670BC    8A46 02____________mov       al, [esi+2]
004670BF    3C 00______________cmp       al, 0
004670C1    74 15______________je        short 004670D8
004670C3     3C 20______________cmp       al, 20
004670C5   75 EE______________jnz       short 004670B5
004670C7    46_________________inc       esi
004670C8    46_________________inc       esi
004670C9    46_________________inc       esi
004670CA    B8 EC704600________mov     eax, 004670EC
004670CF    8930_______________mov       [eax], esi        ;将文件名存入指定的[000670EC]中
004670D1     61_________________popad
004670D2    A1 E0784800________mov       eax, [4878E0]
004670D7    C3_________________retn
004670D8    33C0_______________xor       eax, eax
004670DA   A3 EC704600________mov     [4670EC], eax
004670DF   EB F0______________jmp     short 004670D1

3.将获取的文件名,模拟GetOpenFileNameA函数存入数据结构(在堆栈)中
原    000234A5:FF 15 48 85 46    改为   90 E9 BB 3B 04  (运行到00067066添加的代码)
00067066——00067083是添加的处理文件名的过程:如果有“双击”,则跳过.GetOpenFileNameA,直接将文件名存入[ebp-64]中,如果没有双击,则恢复打开文件功能(程序中的反汇编如下):

00467066    A1 EC704600_______mov     eax, [4670EC]
0046706B    83F8 00____________cmp       eax, 0
0046706E    75 08______________jnz       short 00467078
00467070    FF15 48854600______call      [<&comdlg32.GetOpenFileNameA>]
00467076    EB 0A_____________jmp       short 00467082
00467078      8945 9C____________mov       [ebp-64], eax
0046707B    33C0_______________xor       eax, eax
0046707D    A3 EC704600_______mov       [4670EC], eax
00467082    40_________________inc       eax
00467083     E9 23C4FBFF_______jmp       004234AB

4.截取含有主窗口句柄的代码,取出句柄并建立线程
原    0001876E:E8 C2 F8 FF FF    改为   E9 75 E9 04 00  (运行到00067160添加的代码)
00067160——0006701A1是添加的获取主窗口句柄并建立线程的过程(程序中的反汇编如下):

00467160    A1 EC704600_______mov     eax, [4670EC]
00467165      83F8 00____________cmp       eax, 0
00467168    74 32______________je    short 0046719C   ;若没有双击文件名则不建立新线程
0046716A    A1 E8704600_______mov       eax, [4670E8]    
0046716F     83F8 00____________cmp       eax, 0
00467172     75 28______________jnz       short 0046719C    ;在没有取得句柄前不建立新线程
00467174    8B01______________mov       eax, [ecx]        ;主窗口句柄地址在ecx中
00467176    A3 E8704600_______mov       [4670E8], eax    ;将句柄存入[4670E8]中
0046717B    60________________pushad
0046717C   68 E4704600________push      004670E4    
00467181    6A 00______________push      0  
00467183     6A 00______________push      0  
00467185    68 C0714600________push      004671C0    ;ThreadFunction = flvplaye.004671C0
0046718A   6A 00______________push      0  
0046718C   6A 00______________push      0  
0046718E    FF15 18814600______call      [<&KERNEL32.CreateThread>]
00467194     50_________________push      eax  
00467195     FF15 0C814600______call      [<&KERNEL32.CloseHandle>]    ;CloseHandle
0046719B     61_________________popad
0046719C    E8 0C0FFBFF_______call      004180AD
004671A1   E9 4516FBFF________jmp       004187EB

5.新线程运行时,发出模拟鼠标按下按钮动作的消息
000671C0——00067245是添加的线程过程,线程建立后,自动运行(程序中的反汇编如下):

004671C0    55____________push      ebp
004671C1    8BEC_________mov       ebp, esp
004671C3    BB 10000000___mov       ebx, 10
004671C8    B9 00010000___mov       ecx, 100               ;适当延时,让窗口打开后稳定
004671CD    90____________nop
004671CE    E2 FD_________loopd     short 004671CD
004671D0    4B____________dec       ebx
004671D1    68 E9000600____push    600E9        ;lParam = 600E9 (鼠标坐标,位于按钮范围内)
004671D6    6A 00__________push      0          ;wParam = 0
004671D8    68 00020000____push      200           ;Message = WM_MOUSEMOVE
004671DD    FF35 E8704600__push      dword ptr [4670E8]    ;hWnd 
004671E3    FF15 0C844600__call    [<&USER32.PostMessageA>]  ;PostMessageA
004671E9    83FB 00________cmp       ebx, 0
004671EC   75 DA__________jnz       short 004671C8
004671EE    BB 02000000____mov    ebx, 2
004671F3    B9 00010000____mov       ecx, 100
004671F8    90_____________nop
004671F9    E2 FD__________loopd     short 004671F8
004671FB    4B_____________dec       ebx
004671FC    68 E9000600____push      600E9      ;lParam = 600E9 (鼠标坐标,位于按钮范围内)
00467201    6A 00__________push      0          ;wParam = 0
00467203    68 01020000_____push    201          ;Message = WM_LBUTTONDOWN
00467208    FF35 E8704600__push      dword ptr [4670E8]    ;hWnd 
0046720E    FF15 0C844600__call    [<&USER32.PostMessageA>]   ;PostMessageA
00467214    83FB 00________cmp       ebx, 0
00467217    75 DA__________jnz       short 004671F3
00467219    BB 02000000____mov       ebx, 2
0046721E    B9 00100000____mov       ecx, 1000
00467223    90_____________nop
00467224    E2 FD_________loopd     short 00467223
00467226    4B____________dec       ebx
00467227    68 E9000600____push      600E9        ;lParam = 600E9 (鼠标坐标,位于按钮范围内)
0046722C    6A 00__________push      0            ;wParam = 0
0046722E     68 02020000____push      202            ;Message = WM_LBUTTONUP
00467233    FF35 E8704600__push      dword ptr [4670E8]        ;hWnd 
00467239    FF15 0C844600__call   [<&USER32.PostMessageA>]  ;PostMessageA
0046723F    83FB 00________cmp       ebx, 0
00467242    75 DA__________jnz       short 0046721E
00467244    C9_____________leave
00467245    C2 0400________retn      4

注意:反汇编是程序运行中的地址,文件中的实际地址刚好少400000,只要将反汇编地址中最高位004改为000就是文件中的实际地址了。将文件修改后保存,试一试,是不是可以双击运行文件了?
 因为我没有图片粘贴权限,代码用word书写后拷贝上贴子,代码始终不能对齐,十分难看。