在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++实现会更容易。
本文只作为爱好研究,需要尊重相关作者的商业产权,所以示例代码只公开了用于讲解的部分。所有关于本文及本文有关代码的引用和使用都非本文作者授意授权,由之产生的一切法律责任与本文作者无关!