【问题标题】:Windows API calls from assembly while minimizing program size从程序集调用 Windows API,同时最小化程序大小
【发布时间】:2010-10-30 20:07:25
【问题描述】:

我正在尝试用汇编语言编写一个程序,并使生成的可执行文件尽可能小。我正在做的一些事情需要对WriteProcessMemory 等函数进行Windows API 调用。我在调用这些函数方面取得了一些成功,但是在编译和链接之后,我的程序出现在 14-15 KB 的范围内。 (来自不到 1 KB 的来源)我希望得到的远比这要少得多。

我对做这种低级的事情很陌生,所以我真的不知道需要做什么才能使程序更小。我知道 exe 格式本身占用了相当多的空间。有什么办法可以减少这种情况吗?

我应该提到我正在使用 NASM 和 GCC,但如果有帮助,我可以轻松更改。

【问题讨论】:

  • 你是用汇编写整个程序吗?
  • 出于个人好奇,15kb的可执行文件在什么环境下会变大?
  • 是的,整个程序将在汇编中。我所做的更多是个人挑战,而不是任何实际操作。

标签: winapi assembly linker nasm


【解决方案1】:

我建议使用DumpBin 实用程序(或GNU 的objdump)来确定占用最多空间的内容。它可能是资源文件、巨大的全局变量或类似的东西。

【讨论】:

    【解决方案2】:

    大多数 PE 文件的默认节对齐方式是 4K,以与自然系统内存布局对齐。如果您有 .data、.text 和 .resource 部分 - 已经是 12K。大部分都是0,浪费空间。

    您可以采取一些措施来最大程度地减少这种浪费。首先,将节对齐减少到 512 字节(不知道 nasm/gcc 所需的选项)。其次,合并这些部分,以便您只有一个 .text 部分。尽管对于打开 NX 位的现代机器来说,这可能是一个问题。此安全功能可防止病毒等对可执行代码部分的修改。

    还有大量的 PE 压缩工具可以压缩你的 PE 并在执行时解压缩它。

    【讨论】:

    • NX 不是这样做的。即使没有 NX 功能,包含可执行代码的页面在普通操作系统上也是只读的。 NX 为您提供的是不可可执行的读写数据页。因此,堆栈内存中的缓冲区溢出覆盖返回地址并导致执行跳转到也是缓冲区溢出一部分的机器代码不起作用。跳转到堆栈内存段错误,因为堆栈内存没有启用执行权限。在任何将文本设为只读的系统上,将文本与 data/bss 部分结合起来都会遇到麻烦,但您可以将 .rodata.text 结合起来。
    【解决方案3】:

    请参阅Tiny PE,了解可用于减小可执行文件最终大小的一系列提示和技巧。请注意,该文章中的一些后期技术非常脆弱。

    【讨论】:

      【解决方案4】:

      FWIW,我可以使用 ML 或 ML64 组装的最小程序大约为 3kb。 (这只是说你好世界并退出。)

      【讨论】:

        【解决方案5】:

        给我一​​个小 C 程序(不是 C++),我会告诉你如何用它制作一个 1 ko .exe。我推荐的最小可执行文件大小是 1K,因为如果它不是至少这个大小,它将无法在某些 Windows 上运行。

        您只需使用链接器开关即可实现! polink 是一个很好的链接器。

        如果您在 Assembly 中完成所有操作,那就更容易了。只要去 MASM32 论坛,你就会看到很多这样的程序。

        【讨论】:

        • IMO FASM 更适合这个目的。它可以直接创建可执行文件,并允许您自己定义部分。
        • 是的,FASM 很好。您可以对整个可执行文件进行 DB,这是实现这些小型可执行文件的最佳方式。 Heureusement,我已经设法在 1ko 停止我的精神疾病 :)
        猜你喜欢
        • 2016-08-15
        • 1970-01-01
        • 2010-12-21
        • 2013-06-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-31
        • 1970-01-01
        相关资源
        最近更新 更多