• 标 题:修改flashget的另类方法(已修正)
  • 作 者:runjin
  • 时 间:004-07-25,12:32
  • 链 接:http://bbs.pediy.com

在论坛上看到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 ;直接返回


这样就完完全全可以自定默认目录了