通da信TCP长连接数据算法分析

点击上方蓝字[协议分析与还原]关注我们


 分析通da信TCP长连接内部分数据的算法。

作为一款老牌的炒股软件,通da信里面的数据是相当的丰富,免费的也很丰富,准确性也很好,例如,这种股票之间关联的信息。

通da信一路走来,功能在不停地丰富,具备各个平台的客户端,当然,用的人和机构也很多,这是好事,产品在传承,技术也在继续,例如其客户端的TCP长连接,应该是从PC时代就存在的,在移动终端上也一直在使用,彰显着它的还算可以的技术实力,毕竟,这是一个HTTP接口遍地走的时代,熟悉TCP多线程开发的人也不好找的。

虽然技术不错,但不知具体原因,通da信一直保持TCP连接的未加密模式,大概是技术的迭代需要牵涉到太多的模块,不好搞吧。当然,对爬虫来说,虽然未加密,但TCP连接里面的数据的爬取还是难的哟。

通达信的TCP长连接流量没加密但是,放眼望去,里面的数据也有很多不是明文,不够直观,今天,我们来看看通达信TCP长连接里面数据的情况,对里面的部分数据进行解码,对不懂的人来说,就相当于解密了。

01

报文分析

按照标准流程,分析解密协议要先找到报文流,找到数据流的识别的方法,不过这里没有,大家有兴趣的话自行去找,很好找的。下面直接进行长连接流量的分析。

首先,我们来看下通达信的长连接的大概情况,里面有明文,也有不可见的乱码,明文大概是一些命令和参数,当然还有股票代码:

乱码太多了,从里面找到了一段数据,是wireshark抓的一个完整的TCP包,是一个完整的数据块,以hex转储模式看下原始数据:

粗略的分析下,前面的32字节大概是相当于块头,我们先不管,后面的很长的数据,应该就是传输的内容了,经过一番分析,过程就略掉了,其实直接看数据就能看到,以十六进制的789c开始的数据,大概率是压缩数据,这个拼的是经验,经验不足就去分析代码吧,直接解压试试,结果如下:

不好意思,这是写好的工具的解密结果。

数据是deflate压缩的,解压即可,用python的zlib库很好实现,汉字编码是GBK的,注意下,否则解出来看到就是乱码了,如果反向进行压缩,压缩级别compresslevel选6。

来看看完整复刻编解码版的代码:

def deflate(data, compresslevel=9):
    compress = zlib.compressobj(
            compresslevel,        
            zlib.DEFLATED,        
            -zlib.MAX_WBITS,    
            zlib.DEF_MEM_LEVEL,   
            0                    
    )
    deflated = compress.compress(data)
    deflated += compress.flush()
    return deflated


def inflate(data):
    decompress = zlib.decompressobj(
            -zlib.MAX_WBITS  
    )
    inflated = decompress.decompress(data)
    inflated += decompress.flush()
    return inflated


def dectongdaxin(decoded_data):
    orig= inflate(decoded_data[2:])
    return orig


def enctongdaxin(data):
    orig= deflate(data,6)
    crc=0
    crc = zlib.adler32(data) & 0xffffffff
    return bytes.fromhex('789C')+orig+crc.to_bytes(4, byteorder="big")

很简单的,有兴趣可以自己尝试解密玩玩。

02


结束

长连接数据的解密方法就介绍到这里了,大家有任何对应用流量解密方面的问题可以找我交流,有什么稀奇的东西,也可以给我瞅瞅,交个朋友。最近解了不少游戏和应用,好枯燥噢。

别忘点“在看”、“赞”和“分享”

新的规则,及时收推文要先给公号星标

别忘了星标一下,不然就错过了

长按进行关注,时刻进行交流。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是使用Java连接远程OPC DA协议获取数据的示例代码: ```java import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.jinterop.dcom.common.JIException; import org.jinterop.dcom.core.JIVariant; import org.openscada.opc.lib.common.ConnectionInformation; import org.openscada.opc.lib.da.AccessBase; import org.openscada.opc.lib.da.Item; import org.openscada.opc.lib.da.ItemState; import org.openscada.opc.lib.da.Server; import org.openscada.opc.lib.da.SyncAccess; public class OPCDASample { private static final String CLSID = "F8582CF2-88FB-11D0-B850-00C0F0104305"; private static final String PROG_ID = "OPC.SimaticNET"; private static final String SERVER_HOST = "localhost"; private static final String ITEM_ID = "Random.Int1"; public static void main(String[] args) { ConnectionInformation ci = new ConnectionInformation(); ci.setClsid(CLSID); ci.setProgId(PROG_ID); ci.setHost(SERVER_HOST); ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); try { Server server = new Server(ci, executor); server.connect(); AccessBase access = new SyncAccess(server, 1000); access.addItem(ITEM_ID, new DataCallback()); executor.scheduleAtFixedRate(new Runnable() { @Override public void run() { try { access.bind(); Item item = access.getItem(ITEM_ID); ItemState state = item.read(false); System.out.println("Value: " + state.getValue().getObjectAsInt()); access.unbind(); } catch (Exception e) { e.printStackTrace(); } } }, 0, 1, TimeUnit.SECONDS); } catch (Exception e) { e.printStackTrace(); } } private static class DataCallback extends AccessBase { @Override public void dataChange(Item item, ItemState state) { try { Object value = state.getValue().getObject(); if (value instanceof JIVariant) { value = ((JIVariant)value).getObject(); } System.out.println("Callback Value: " + value); } catch (JIException e) { e.printStackTrace(); } } } } ``` 在上面的示例代码中,我们使用了 `org.openscada.opc.lib` 库来连接OPC DA服务器并获取数据。其中: - `ConnectionInformation` 类用于指定OPC DA服务器的连接息,包括 CLSID、ProgID、主机名等。 - `Server` 类用于连接OPC DA服务器。 - `AccessBase` 类提供了访问OPC DA服务器中某个数据项的方法。 - `SyncAccess` 类是 `AccessBase` 的子类,提供了同步读取数据的方法。 - `Item` 类表示OPC DA服务器中的一个数据项。 - `ItemState` 类表示数据项的状态,包括当前值、质量等息。 - `DataCallback` 类继承了 `AccessBase`,用于处理数据项的变化。 在上面的代码中,我们使用了一个定时任务来读取数据项的值。可以根据实际需求进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值