Clear CTP namespace pollution

@vrqq  May 24, 2021
起因是发现ctp库和mysqlconn冲突,然后打符号表瞅瞅好家伙X509,AES好家伙合着Openssl全露在外头。。

看了下CTPse for linux的 6.3.15 6.13.19 和ctpmini 都有如此问题,干脆直接包一层

llvm-nm --just-symbol-name ./thosttraderapi_se.so > tradesym.txt
llvm-nm --just-symbol-name ./thostmduserapi_se.so > marketsym.txt

(我在这里用了llvm-nm 其实用啥都行) 先导出符号表看看,我们只需要class CThostFtdcTraderApiclass CThostFtdcMdApi即可,故在生成的txt中搜索上述关键词,发现如下相关项:

_ZN19CThostFtdcTraderApi13GetApiVersionEv
_ZN19CThostFtdcTraderApi19CreateFtdcTraderApiEPKc
_ZTI19CThostFtdcTraderApi
_ZTS19CThostFtdcTraderApi
_ZTV19CThostFtdcTraderApi

_ZN15CThostFtdcMdApi13GetApiVersionEv
_ZN15CThostFtdcMdApi15CreateFtdcMdApiEPKcbb
_ZTI15CThostFtdcMdApi
_ZTS15CThostFtdcMdApi
_ZTV15CThostFtdcMdApi

故制作如下dll-loader

#ifdef __linux__

#include <cassert>
#include <dlfcn.h>
#include "ThostFtdcMdApi.h"
#include "ThostFtdcTraderApi.h"

static void* TradeClass  = dlopen("thosttraderapi_se.so.6.3.15", RTLD_NOW | RTLD_LOCAL);
static void* MarketClass = dlopen("thostmduserapi_se.so.6.3.15", RTLD_NOW | RTLD_LOCAL);

CThostFtdcMdApi *CThostFtdcMdApi::CreateFtdcMdApi
(const char *pszFlowPath, const bool bIsUsingUdp, const bool bIsMulticast)
{
    assert(MarketClass);
    using T=decltype(&CThostFtdcMdApi::CreateFtdcMdApi);
    void *fn=dlsym(MarketClass, "_ZN15CThostFtdcMdApi15CreateFtdcMdApiEPKcbb");
    return ((T)fn)(pszFlowPath, bIsUsingUdp, bIsMulticast);
}

const char *CThostFtdcMdApi::GetApiVersion()
{
    assert(MarketClass);
    using T=decltype(&CThostFtdcMdApi::GetApiVersion);
    void *fn=dlsym(MarketClass, "_ZN15CThostFtdcMdApi13GetApiVersionEv");
    return ((T)fn)();
}


CThostFtdcTraderApi *CThostFtdcTraderApi::CreateFtdcTraderApi(const char *pszFlowPath)
{
    assert(TradeClass);
    using T=decltype(&CThostFtdcTraderApi::CreateFtdcTraderApi);
    void *fn=dlsym(TradeClass, "_ZN19CThostFtdcTraderApi19CreateFtdcTraderApiEPKc");
    return ((T)fn)(pszFlowPath);
}

const char *CThostFtdcTraderApi::GetApiVersion()
{
    assert(TradeClass);
    using T=decltype(&CThostFtdcTraderApi::GetApiVersion);
    void *fn=dlsym(TradeClass, "_ZN19CThostFtdcTraderApi13GetApiVersionEv");
    return ((T)fn)();
}

#endif

答疑时间

vtable是怎么体现的?
vtable通过.h里面的定义体现,virtual函数按顺序排在vtable[]里

RTTI呢?
TBD 没研究

还有其他方案吗?

  • AST 对.h文件跑语法分析 例如 clang-query, 没研究过
  • 找到使用它的binary文件(elf),然后打函数导入表import table (dumpbin /import)

附录 这glibc版本太低啊!

先去网上拖一个 https://ftp.gnu.org/gnu/glibc/
以rhel举例,先装个scl,装好后更新软件源 会出现devtoolset-10,装之。然后使用scl enable devtoolset-10 bash切过去

附录 glibc解决了 但是奇奇怪怪的依赖又不行了

直接上container好啦! docker或者podman,rhel系首选podman
RHEL订阅者可选 rhel8/gcc-toolset-10-toolchain 备注最新的License: https://www.redhat.com/en/blog/new-year-new-red-hat-enterprise-linux-programs-easier-ways-access-rhel

## ====== In Host ======
podman run --cap-add=SYS_PTRACE --ulimit memlock=-1 --name devnc -d -it -v/root/deployment/rrun:/root/rrun:z docker.io/library/centos

## ====== In container ======
## Converting from CentOS Linux 8 to CentOS Stream 8
dnf swap centos-linux-repos centos-stream-repos
dnf distro-sync

## Install support of codecvt/locale in c++ STL, and gcc libstdc++
dnf install glibc-langpack-zh libstdc++

## (optional) Install gdb
dnf install gdb

好啦可以运行啦

  • 在宿主机attach podman attach devnc
  • 在container时 detach ctrl + p q

添加新评论