在论坛上看到RoBa修改flashget如此有意思,我也忍不住用自己的方法试了一下.
修改flashget 的另类方法(1.60a)
我的思路是这样的:在flashget的添加下载任务的窗口里,有许多文本框,下载目录就显示在其中的一个文本框里,默认是:c:\downloads ,我想,它总要调用SetWindowTextA函数来显示,那好,我就在它掉用那个函数的时候做手脚,让它以日期作为目录名来显示.
先是给 flashget 加入kernel32.dll里的 GetDateFormatA函数,我们亲自动手,用Winhex打开flashget.exe ,在文件偏移3c处看到:18 01 00 00 ,倒过头就是 pe header的偏移地址:
00000118 ,那么导入表的指针地址就是: 118+80=198 ,看到偏移198 处,是: 18 64 12 00 ,倒过来就是: 00126418 ,呵呵,这就是导入表的RVA了,在文件中的实际偏移刚好也是: 126418 .
从126418处往下搜索 kernel32.dll 找到在 127b38 ,rva 也是这个,好,再往上查找16进制值:387b1200 ,找到在0012644c ,这里就是对应着kernel32.dll的IID的 Name项,看到它后面的双字项么,那就是 First Thunk ,指向对应着kernel32.dll的IAT部分,它也是个RVA,这里的值是:7cf10f00,倒过来就是:FF17C ,找到FF17C,从FF17C向下找00000000 ,把从FF17c到找到地址的区块复制到一块空白的地方,好了,再在另一块空白的地方写入GetDateFormat 的子窜,假设其地址是12a000,然后我们就在刚才复制的数据后面加上00a01200,假设加入这个地址的所在地为12b000 ,这个12b000是最有用的地方了,我们在程序中调用GetDateFormat的方法是:call dword ptr [image base+0012b000] ,好了,函数表修好了.
在flashget正常运行后,bpx setwindowtexta ,然后点击"添加"按钮,程序被中断,如下:
004D60A9 8B41 38 MOV EAX,DWORD PTR DS:[ECX+38]
004D60AC 85C0 TEST EAX,EAX
004D60AE 75 0F JNZ SHORT flashget.004D60BF
004D60B0 FF7424 04 PUSH DWORD PTR SS:[ESP+4]
004D60B4 FF71 1C PUSH DWORD PTR DS:[ECX+1C]
004D60B7 FF15 8CF64F00 CALL DWORD PTR DS:[<&USER32.SetWindowTex>; USER32.SetWindowTextA
004D60BD EB 0E JMP SHORT flashget.004D60CD
setwindowtexta函数有两个参数,原型是:BOOL SetWindowText(HWND hwnd,LPCTSTR lpStrjng)
压栈时是"first in last out" ,所以, 4d60b0 处是文本的地址,下面的是对象的句柄地址,看看它所指向的地址处,并非"c:\downloads" ,最后发现这里是关键:
00529780 FF75 0C PUSH DWORD PTR SS:[EBP+C]
00529783 FF75 08 PUSH DWORD PTR SS:[EBP+8]
00529786 FF15 8CF64F00 CALL DWORD PTR DS:[<&USER32.SetWindowTex>; USER32.SetWindowTextA
0052978C 5E POP ESI
0052978D C9 LEAVE
0052978E C2 0800 RETN 8
而其它文本的显示都在这个地方,关键是ebp的值不同,但这里用ebp的值作为判断是不行的,自己试试就知道为什么了.我把代码写在529700处,所以改为:
004DCB15 74 0C JE SHORT flashget.004DCB23
004DCB17 E9 E4CB0400 JMP flashget.00529700
004DCB1C 90 NOP
004DCB1D FF15 8CF64F00 CALL DWORD PTR DS:[<&USER32.SetWindowTex>; USER32.SetWindowTextA
004DCB23 5E POP ESI
004DCB24 C9 LEAVE
004DCB25 C2 0800 RETN 8
自己写入的代码如下:
00529700 81FD C0E51200 CMP EBP,12E5C0
00529706 75 78 JNZ SHORT flashget.00529780
00529708 83FB 02 CMP EBX,2
0052970B 75 73 JNZ SHORT flashget.00529780;判断控件
0052970D 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C]
00529710 BF 90985200 MOV EDI,flashget.00529890
00529715 A5 MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ES];复制默认目录
00529716 B8 90985200 MOV EAX,flashget.00529890
0052971B 8A18 MOV BL,BYTE PTR DS:[EAX]
0052971D 83C0 01 ADD EAX,1
00529720 80FB 00 CMP BL,0
00529723 ^ 75 F6 JNZ SHORT flashget.0052971B;获得地址,为合并作准备
00529725 83E8 01 SUB EAX,1;减1才是正确的地址
00529728 8BD8 MOV EBX,EAX
0052972A 50 PUSH EAX
0052972B 6A 0A PUSH 0A
0052972D 50 PUSH EAX
0052972E 6A 00 PUSH 0
00529730 6A 00 PUSH 0
00529732 6A 01 PUSH 1
00529734 6A 00 PUSH 0
00529736 FF15 1E605B00 CALL DWORD PTR DS:[<&kernel32.GetDateFor>; KERNEL32.GetDateFormatA 获得日期
0052973C 68 90985200 PUSH flashget.00529890 ; ASCII "c:\downloads\"
00529741 FF75 08 PUSH DWORD PTR SS:[EBP+8]
00529744 FF15 8CF64F00 CALL DWORD PTR DS:[<&USER32.SetWindowTex>; USER32.SetWindowTextA 显示目录
0052974A B8 00000000 MOV EAX,0
0052974F 8903 MOV DWORD PTR DS:[EBX],EAX;清除手尾,否则目录会越变越长
00529751 5E POP ESI
00529752 C9 LEAVE
00529753 C2 0800 RETN 8 ;直接返回
下面的是窗口中其它文本的显示处理:
00529780 FF75 0C PUSH DWORD PTR SS:[EBP+C]
00529783 FF75 08 PUSH DWORD PTR SS:[EBP+8]
00529786 FF15 8CF64F00 CALL DWORD PTR DS:[<&USER32.SetWindowTex>; USER32.SetWindowTextA
0052978C 5E POP ESI
0052978D C9 LEAVE
0052978E C2 0800 RETN 8 ;直接返回
这样就完完全全可以自定默认目录了