当前位置: 首页 > 工具软件 > MT4j > 使用案例 >

MT4 .srv 文件解析(提取mt4主服务器及DC服务器地址)

史智志
2023-12-01

在mt4客户终端的数据目录子目录config 中包含着一些后缀为 .srv的文件,这种文件一般以经纪商名字作为文件名,记录着经纪商主服务器及Data Center 服务器的地址(ip/域名和端口)和ping记录等信息。
srv文件可分为两大部分:经纪商主要服务器信息(main)和从服务器信息(slaves)。

主要服务器信息可能由于使用频繁,不加密存储,其关键字段为:

        0...0x3f:           broker name
        0x40...0xbf:        description
        0xd9...0x0x15a:     host address
        0xc0(int32):        is demo?
        0xc4(int32):        ping time
        0xd4(int32):        slave block count

可以直接使用c/c++结构进行映射。

从服务器信息块从文件偏移0x160开始,是一个数组,内含0或多个从服务器(或DC)信息,每个信息结构长度为0xA0。整个从服务器信息块使用双字节相关异或加密,参与加密的密钥长度为16个字节,固定不变。其关键字段如下:

        0x0...0x3f:     server address
        0x44...0x84:    description
        0x90(int32):    ip internal
        0x94(int32):    ping time

除关键字段外,还有若干不重要字段如是否代理,优先顺序等。

以下描述重点:从服务器信息块的加密算法

从terminal逆向到解密代码块,key 固定为41 B6 7F 58 38 0C F0 2D 7B 39 08 FE 21 BB 41 58

010E32AA    | mov eax,edi                                  |
010E32AC    | mov ecx,ebx                                  | ecx = encoded-data
010E32AE    | sub eax,ebx                                  |
010E32B0    | mov ebx,eax                                  | ebx = encoded-data-len
010E32B2    | mov eax,edx                                  | eax = 0
010E32B4    | lea ecx,dword ptr ds:[ecx+1]                 |
010E32B7    | and eax,F                                    | i<eax> = counter % 0xF
010E32BA    | inc edx                                      | edx = counter
010E32BB    | mov al,byte ptr ds:[eax+<?key>]              |
010E32C1    | add al,byte ptr ss:[ebp-4]                   | var_4
010E32C4    | xor al,byte ptr ds:[ecx-1]                   | [ecx-1] = current byte
010E32C7    | mov byte ptr ds:[ebx+ecx-1],al               |
010E32CB    | movsx eax,byte ptr ds:[ecx-1]                |
010E32CF    | mov dword ptr ss:[ebp-4],eax                 |
010E32D2    | cmp edx,esi                                  |
010E32D4    | jl terminal.10E32B2                          |

用nodejs实现一下如下:

        let decrypt = function (buf, start, end = 0) {
            if (end === 0) end = buf.byteLength;

            let outbuf = Buffer.alloc(end - start);

            let tmp = 0;
            let j = 0;
            for (let i = start; i < end; i++) {
                let k = decryptKey[j & 0xF];
                k += tmp;
                k ^= buf[i];
                outbuf[j++] = k;
                tmp = buf[i];
            }

            return outbuf;
        };

当然,使用c/c++实现会更容易。

本文只作为爱好研究,需要尊重相关作者的商业产权,所以示例代码只公开了用于讲解的部分。所有关于本文及本文有关代码的引用和使用都非本文作者授意授权,由之产生的一切法律责任与本文作者无关!

 类似资料: