怎么判断程序是c c++ golang python写的

好问题 👍,SRE 工程里经常会遇到一个二进制文件(比如 /usr/bin/xxx),但不知道它是用 C、C++、Go、Python(或其他语言)写的。
判断语言通常不靠“看代码”,而是看 二进制文件特征

我分几类方法给你:


🔹 1. 用 file 看基础信息

file /usr/bin/nginx

输出类似:

/usr/bin/nginx: ELF 64-bit LSB executable, x86-64, dynamically linked ...

这只能告诉你是 ELF 可执行文件(Linux 下的标准格式),不能直接区分 C / C++ / Go。


🔹 2. 用 strings + grep 找语言特征

strings /usr/bin/myapp | less
  • Go 二进制:几乎总能看到 runtime.goexitruntime.maintype.*go.itab 等符号。

    strings mygoapp | grep -i 'go.'
    
  • C++ 二进制:会看到很多 _Z 开头的符号(这是 C++ 名字修饰/mangling)。

    strings mycppapp | grep '_Z'
    
  • Python 程序打包成二进制(PyInstaller/PyOxidizer):能看到 Py_InitModulePyObject.pyc、模块名字等。

  • 纯 C 程序:一般只有正常的函数名、库函数(printf, malloc),没有 _Z 符号,也没有 Go runtime。


🔹 3. 用 nmobjdump 看符号表

nm -D /usr/bin/myapp | less
  • Go

    U runtime.morestack
    U runtime.goexit
    
  • C++

    0000000000401140 T _ZSt4cout
    0000000000401180 T _ZNSolsEi
    
  • C

    0000000000401040 T main
    U printf
    
  • Python (C API)

    U Py_Initialize
    U PyRun_SimpleString
    

🔹 4. 用 ldd 看依赖库

ldd /usr/bin/myapp
  • Go 静态编译的二进制:通常只有 linux-vdso.so.1 或完全 no dynamic dependencies

  • C / C++:会链接 libc.so, libm.so, libstdc++.so(C++ 才有)。

  • Python:会看到 libpython3.x.so


🔹 5. 用 readelf 看 section

readelf -S /usr/bin/myapp | grep -i dynstr
  • Go 二进制里有 .gopclntab.gosymtab 段,这是 Go runtime 自带的调试信息。

  • C/C++ 没有这些,只有常规 ELF 段。


🔹 6. 实战对比例子

  1. Nginx(C 写的):

    strings $(which nginx) | grep runtime.goexit   # 没有
    ldd $(which nginx)  # 依赖 libc.so
    
  2. Etcd(Go 写的):

    strings $(which etcd) | grep runtime.goexit   # 有
    ldd $(which etcd)  # 可能只有 vdso,没有 libc.so
    
  3. Redis(C 写的):

    nm -D $(which redis-server) | grep _Z   # 没有 _Z
    
  4. Fluent-bit(C 写的,SRE 常用日志 agent):

    ldd $(which fluent-bit) | grep stdc++   # 没有,说明是 C,不是 C++
    
  5. 某个 C++ 程序

    nm -D ./app | grep _Z   # 一堆 _Z... 符号
    

总结方法:

  1. strings → 看 runtime 特征(Go、Python 很明显)。

  2. nm / objdump → 看符号,C++ 有 _Z*,Go 有 runtime.*,Python 有 Py_*

  3. ldd → 看依赖库(libc、libstdc++、libpython)。

  4. readelf → 看特殊段(Go 有 .gopclntab)。


要不要我写一个 小脚本 (bash/Python),可以自动判断二进制大概是 C / C++ / Go / Python 的?这样你丢个文件进去就能一键分析。

posted on 2025-09-05 16:09  吃草的青蛙  阅读(54)  评论(0)    收藏  举报

导航