在Python脚本中执行嵌入的.exe文件

6

如何将一个以base64编码的exe文件加载到内存中并执行,而不必将其写入磁盘?

这样做的目的是为了建立一种控制/密码/序列系统,并使用py2exe进行编译。然后,我可以在代码中随时执行该嵌入式文件。


我猜你是在用Windows系统?为什么不在Python中实现二进制原生性呢? - tMC
tMC:这是一个Flash可执行文件。 - leferreyra
@leferreyra:大多数用户只需将文件隐藏在临时目录中即可被欺骗。而那些不会被欺骗的人...嗯,任何阅读过基本破解教程的人都知道如何在内存中获取图像并将其保存到磁盘和/或从您的源代码中解码它,因此最多只能将破解软件所需的时间延长几分钟。这值得你花费数小时的工作(并且很可能会给你的合法用户带来错误)吗? - abarnert
@abarnert 是的,我知道最终它会被破解。我只是认为从临时目录复制可执行文件比内存/二进制分析要容易得多。但考虑到这个应用程序的目标用户,我不会太担心。 - leferreyra
@leferreyra:我的观点是这并不容易。对于任何曾经破解过东西的人来说,两者都很简单;对于非破解者来说,两者都超出了他们的能力范围。只有极少数人处于中间地带。复制保护始终涉及权衡,在这种情况下,收益如此微小,以至于几乎任何成本都会超过它。 - abarnert
显示剩余2条评论
2个回答

7
所有 Python 用于执行子进程的机制都需要一个文件名。
而 Win32 API 中的底层 CreateProcess 函数也需要一个文件名,因此即使降至该级别也没有简单的解决方法。
当然,可以通过转向 ZwCreateProcess/NtCreateProcess 来实现这一点。如果您知道如何使用低级 NT API,这篇文章 就足够让您理解了。如果您不知道……在 SO 回答中解释这些内容是过于繁琐的。
或者,您当然可以创建或使用 RAM 磁盘,甚至模拟虚拟文件系统,但这种做法有点过于荒谬,只是为避免创建文件而已。
因此,正确的做法是将 exe 写入文件,然后执行它。例如,像这样:
fd, path = tempfile.mkstemp(suffix='.exe')
code = base64.b64decode(encoded_code)
os.write(fd, code)
os.fchmod(fd, 0o711)
os.close(fd)
try:
    result = subprocess.call(path)
finally:
    os.remove(path)

这应该适用于Windows和*nix,但它完全没有经过测试,在至少一个平台上可能会有错误。

显然,如果你想多次执行它,请在完成后不要删除它。或者只需使用一些适当的持久目录,仅在缺失或过期时才编写它。


1
好的,看起来没有简单的方法可以做到这一点,我也不想深入了解Windows API,所以我猜我只能将它写在某个不太常见的临时文件中。 - leferreyra

0

编码exe:

import base64
#encode exe file in base64 data

with open("Sample.exe", 'rb') as f:
    read_exe_to_basae64 = base64.b64encode(f.read())
    

#encoded data will be like (really big text, don't worry) for e.g.: 
b'TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyAAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAAA9AHveeWEVjXlhFY15YRWN+n0bjXhhFY0QfhyNfmEVjZB+GI14YRWNUmljaHlhFY0AAAAAAAAAAAAAAA'

#decode exe file:

with open("Sample2.exe", 'wb') as f: 
    f.write(base64.b64decode(read_exe_to_basae64))

exe文件将被创建在文件夹中。如果您不希望用户看到它,只需将其解码到任意随机文件夹中,并在使用后删除。


1
目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接