打开 exe 文件,最直接的方式就是右键选“属性”,里面有个“详细信息”和“兼容模式”,但那是给新手看配置才用的,实际搞懂它,得靠看看它的脚本来数手筋。 大量人会认定拆解 exe 就是找一堆 C 代码要么 Python 文件,大错特错,那些只是被打包进 exe 里的代码,就像把书撕成碎片,还得自己拼回去。真正的“语言指纹”,往往藏在那些干巴巴的系统调用里。 比如你打开一个挖矿程序,你会看到一行行 `CryptGenRandom` 要么 `NtSecureBoot` 的函数调用。

要是把这行代码复制下来,在搜索框搜 `CryptGenRandom`,根本能搜到几十上百个来源,包含微软官方的核心 SDK、第三方开源库就连某些被黑产反向工程的脚本。

要是搜不到,那根本就确认它是自己写的原生代码了,要么用了贼罕见的第三方库。 再比如一个常见的反监管工具,你看到它每隔几毫秒就调用一次 `WriteProcessMemory` 把数据追加到某个句柄里,这简直不用猜,99% 概率是 Java 要么 C 写的。你就连能顺着这行代码往上扒,找到对应的 `Main` 类要么某个特定的 `Manager` 类,再顺着 `_Static` 要么 `DllImport` 的说明看看底层是调了哪个 DLL,最终就能拼出来。 还有一种更隐蔽的情况,就是那些真正的大厂内部工具。它们的逻辑可能写得贼晦涩,就连故意避开常见的循环和异常处理,用宏要么反编译的中间码来掩盖。

这时候就得靠“语言学”本事了。就像解数学题,有时光看步骤不够,还得看“人话”和“潜台词”。

要是 exe 里全是 `memset`、`strcpy` 这种 Windows 特有的函数,那大约率还是 C 或 C++。

要是全是 `new`、`delete`、`System.Runtime.InteropServices.Marshal`,那根本就是 .NET 了。

要是连这些标准库都碰不到,那就更费事了,可能需求手动去搞 DMA 要么找内存映射段。 有时候你会问,是不是确实能找到源码就完事了?实际上不然。真正的难点在于,开发者可能根本没把代码贴出来,要么贴在了一个全是注释的 `.asm` 里,要么是被极度压缩的字节流。

这时候就需求借助一些专门的工具,比如 Hook、Static、或是一些反编译软件。

这些工具的原理都是“把话挑出来”,它们会去抓取 exe 里的内存地址,去追踪那些特定的函数调用链,就连通过字节标记去推测之类的代码。 举个例子,我昨天分析过一个怪的打包软件。它表面上看全是 `printf_s` 和 `sprintf_s`(带广字符的),让人一眼就当作是 VB6 要么早期的 C++ 风格。但深入之后才发现,它实际上是用 C++11 写的,只是把宏定义改得跟 VB 挺像,把 `std::string` 包装成了 `str_` 前缀,就连故意把一些内联函数全当成赋值的动作。

这种写法在 C++ 圈子里叫“伪代码”要么“方言风格”,要是不专门学这种语法,一般会被误判为 C 或 VB。

这时候,工具的功能就体现出来了,它能自动识别这些特殊的命名约定,帮你还原出原本正常的逻辑流。 自然,这种方式有局限。

要是 exe 是动态链接库,那你可能一辈子都看不到它是如何链接在一起的,要不就你有权限直接读内存要么用一些特殊的分析器。

要是是真正的原生代码,比如某些老旧的 DOS 工具要么嵌入式软件,它们的结构可能贼紧凑,就连没有明显的函数入口,这时候“看表”和“数参数”就成了唯一的路。 另外,还要寻思版本和架构。 exe 的语法不仅取决于语言,还取决于架构(比如 x64 和 x86 的函数名彻底不同)还有操作系统版本(比如 Windows 10 和 11 对某些函数签名的要求)。

故此,要是你看到一个 `wtf` 要么 `wtf2` 开头的类,别急着说这是 VB,大约率是某个框架为了兼容旧环境特意加的包装。 最终,要是想要彻底搞明白,最好的方式就是不要只盯着 exe 看,而是直接去下载它所在的包管理器要么原始安装程序。大量时候, exe 只是那个大包的指纹,真正的逻辑在那些 `.csproj`、`.vbproj` 要么 `.py` 文件里。

有时候就连两个 exe 放在一起,一个负责打包,一个负责运行,这时候看运行那个软件的源码,往往比猜 exe 里的代码更靠谱。 总而言之,看 exe 就像看人讲话,看代码就像看病历。别看直接拿到病历(源码)最好,但大量时候你只能透过那个包裹(exe)看到里面的核心症状。

这时候就需求一点耐心,结合工具的使用,就连带上一点点直觉,才能把那些隐藏在字节流里的“人话”给挖出来。