【文章标题】: 修正傲游2使用socks5代理的bug
【文章作者】: ttqq
【作者邮箱】: tanchi@tom.com
【软件名称】: 傲游浏览器 Maxthon 2.0.8.1720 UNICODE
【软件大小】: 3,158 KB
【下载地址】: http://www.maxthon.cn/
【加壳方式】: 无
【编写语言】: MSVC
【使用工具】: OllyDbg, IDA Pro
【操作平台】: WIN2000
【软件介绍】: 上网啊
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  背景:maxthon2在使用socks5代理上网时,对url进行本地域名解析,若内网中无法DN解析,则导致无法上网。
  
  这里尝试修改这个问题,改用远程DNS。  无脱壳、破解等内容,高手见笑。
  btw: 用代理上网的单位不在少数,很多无法本地域名解析,其他软件都是先尝试本地解析,不成功再远程解析,一般说代理服务器端可以对外访问也就可以解析DN。遨游到好,本地解析不了,就返回错误提示了。
  
  关键是 MxProxy2.dll,先IDA静态看看,再OllyDbg载入maxthon.exe跟一下
  
  下面贴代码,在MxProxy2.dll的.text段,看我的注释(原来笔记是用en的,见谅)
  ========================================================================
  1. crack for no use domain name resolution 强制跳过本地解析
  ========================================================================
  original code:
  base address is 0x00350000
  
  0036D936   .  8B7424 0C     mov     esi, dword ptr [esp+C]
  0036D93A   .  8B46 04       mov     eax, dword ptr [esi+4]
  0036D93D   .  85C0          test    eax, eax
  0036D93F   .  74 3F         je      short 0036D980
  0036D941   >  50            push    eax                              ; /pAddr 记下这个域名字符串的地址,后面用
  0036D942   .  FF15 E8523C00 call    dword ptr [<&WS2_32.#11>]        ; \inet_addr
  0036D948   .  8BF8          mov     edi, eax
  0036D94A   .  83FF FF       cmp     edi, -1
  0036D94D   .  74 07         je      short 0036D956                   ; jump if not ip address
  0036D94F   >  8BC7          mov     eax, edi
  0036D951   .  5E            pop     esi
  0036D952   .  5F            pop     edi
  0036D953   .  C2 0400       retn    4
  0036D956   >  8B56 04       mov     edx, dword ptr [esi+4]
  0036D959   ?  85D2          test    edx, edx
  0036D95B   .  74 1C         je      short 0036D979
  0036D95D   >  52            push    edx                              ; /Name
  0036D95E   .  FF15 04533C00 call    dword ptr [<&WS2_32.#52>]        ; \gethostbyname
  0036D964   .  85C0          test    eax, eax
  ========================================================================
  
  modified code: 随便返回一个整数,不能为-1
  
  0036D956   >  BF 78563412   mov     edi, 12345678                    ; return a random integer, but not -1
  0036D95B   .^ EB F2         jmp     short 0036D94F
  
  
  
  ========================================================================
  2. crack for socks5 connect command
  ========================================================================
  修改socks5协议报文,主要对 connect 报文,参考 rfc1928
  怎么找到这里的?一步步跟下来的啊
  
  original code:
  base address is 0x00350000
  
  0036FA0D    83C4 0C         add     esp, 0C
  0036FA10    B8 9CFF3D00     mov     eax, 003DFF9C            ; address is relocated
  0036FA15    8B10            mov     edx, dword ptr [eax]     ; get 0x01000105 to edx
  0036FA17    8995 80F3FFFF   mov     dword ptr [ebp-C80], edx ; write "05 01 00 01" to buffer, pls refer to rfc1928
  0036FA1D    8B85 30F3FFFF   mov     eax, dword ptr [ebp-CD0] ; get ip which is a dword integer
  0036FA23    8985 84F3FFFF   mov     dword ptr [ebp-C7C], eax ; write ip to buffer, pls refer to rfc1928
  0036FA29    0FB785 7CF3FFFF movzx   eax, word ptr [ebp-C84]  ; get port which is returned by ntohs()
  0036FA30    66:8985 88F3FFFF mov     word ptr [ebp-C78], ax  ; write port to buffer, pls refer to rfc1928
  0036FA37    8B55 2C         mov     edx, dword ptr [ebp+2C]  ; get socket
  0036FA3A    8B4D EC         mov     ecx, dword ptr [ebp-14]
  0036FA3D    8D85 80F3FFFF   lea     eax, dword ptr [ebp-C80] ; get buffer ptr
  0036FA43    6A 0A           push    0A                       ; datasize
  0036FA45    50              push    eax                      ; data buffer. it will jump back from crack code
  0036FA46    52              push    edx                      ; socket
  0036FA47    E8 20E1FFFF     call    0036DB6C                 ; send buffer
  0036FA4C    85C0            test    eax, eax
  ========================================================================
  
  上面的过程是:从0036FA10开始构造报文,到0036FA43压入参数,0036FA47发出去
  我要改成:0036FA10 跳转到新的构造报文的代码,执行完后返回至0036FA45
  
  a.为什么要返回到 0036FA45,而不是 0036FA43,因为第三个参数是报文字节数,我们修改了报文,长度自然也变了,要在我们的代码里处理
  b.新代码我在.text段的最后找了一段空白,用OllyDbg写进去,这里是003BCF00
  c.一开始 0036FA10 处,直接改为了 jmp 003BCF00,机器码是 E9 EBD40400,将这个保存到原文件,运行出错。
    再次载入跟到这里一看,跳转地址变成了一个无效地址。每次都一样,搞了好久解决不了。
    灵感一来,查了一下 reloc表,原来 0036FA11 处的地址进行了重定位,跳过它,搞定
  
  modified code:
  
  0036FA0D   . /EB 06         jmp     short 0036FA15           ; skip address reloc
  0036FA0F     |90            nop
  0036FA10     |90            db      90
  0036FA11   . |9090C580      dd      80C59090                 ; see! already reloc, raw byte is "90 90 90 90"
  0036FA15   > \83C4 0C       add     esp, 0C
  0036FA18   .  E9 E3D40400   jmp     003BCF00                 ; jmp to crack code
  ========================================================================
  
  the following is my crack code, 
  find free space in code segment of .text section for write the code
  
  003BCF00   > \B8 05010003   mov     eax, 3000105
  003BCF05   .  8D9D 80F3FFFF lea     ebx, dword ptr [ebp-C80]
  003BCF0B   .  8903          mov     dword ptr [ebx], eax     ; write "05 01 00 03" to buffer
  003BCF0D   .  83C3 04       add     ebx, 4
  003BCF10   .  8B45 68       mov     eax, dword ptr [ebp+68]  ; get size of domain name, no ending NUL
  003BCF13   .  8803          mov     byte ptr [ebx], al       ; write size to buffer
  003BCF15   .  83C3 01       add     ebx, 1
  003BCF18   .  56            push    esi
  003BCF19   .  57            push    edi
  003BCF1A   .  33C9          xor     ecx, ecx
  003BCF1C   .  08C1          or      cl, al
  003BCF1E   .  8BFB          mov     edi, ebx
  003BCF20   .  8B75 64       mov     esi, dword ptr [ebp+64]
  003BCF23   .  03D9          add     ebx, ecx
  003BCF25   .  F3:A4         rep     movsb                    ; write domain name to buffer
  003BCF27   .  0FB785 7CF3FFFF movzx   eax, word ptr [ebp-C84] ; 以下两行copy自原来的指令
  003BCF2E   .  66:8903       mov     word ptr [ebx], ax       ; write port to buffer
  003BCF31   .  8D85 80F3FFFF lea     eax, dword ptr [ebp-C80]
  003BCF37   .  2BD8          sub     ebx, eax
  003BCF39   .  83C3 02       add     ebx, 2
  003BCF3C   .  8B55 2C       mov     edx, dword ptr [ebp+2C]  ; 以下两行copy自原来的指令
  003BCF3F   .  8B4D EC       mov     ecx, dword ptr [ebp-14]
  003BCF42   .  5F            pop     edi
  003BCF43   .  5E            pop     esi
  003BCF44   .  53            push    ebx                      ; push size of buffer 压入修改过的报文的字节数
  003BCF45   .^ E9 FB2AFBFF   jmp     0036FA45
  003BCF4A   .  90            nop
  
  还记得上面记下的域名字符串的地址?在stack窗口查了一下,[ebp+64]是域名字符串指针,[ebp+68]是字符串字节数(不含结尾的NUL),正好用上
  
  将这段代码保存到原文件,测试,成功了
  
--------------------------------------------------------------------------------
【经验总结】
  对高手来说,这个太简单了。主要是对socks5协议的理解。
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2008年02月22日 21:31:58