won*_*ton 5 security binaryfiles hex-editors
假设我们在这里有这个程序
class Message{
public static SUPER_SECRET_STRING = "bar";
public static void Main(){
string SECRET = "foo";
Console.Write(sha(SUPER_SECRET_STRING) + "" + sha(SECRET));
}
}
Run Code Online (Sandbox Code Playgroud)
现在,在构建此程序之后,有没有办法使用十六进制编辑器或其他实用程序从编译的二进制文件中提取值"foo"和"bar"?
另外,我们假设不允许使用内存编辑器.
这适用于所有编译语言,如C++吗?那些在Java或C#等其他环境中运行的是什么?
是的,您可以轻松地使用反编译器来提取这些常量,尤其是字符串(因为它们需要更大的内存块).这甚至可以在机器码二进制文件中使用,对于Java和C#等VM语言来说更加容易.
如果你需要在那里保守秘密,你需要付出很大的努力.例如,简单地加密字符串会增加一层安全性,但对于知道自己做了什么的人来说,这不会是一个很大的障碍.例如,扫描具有不常见熵的地方的文件可能会显示用于加密的密钥.甚至有甚至通过改变二进制中使用的低级命令来编码秘密的系统.这些工具用其他等效命令替换某些命令组合.但即使是不太难以规避的系统,因为不常见的命令组合将揭示这些工具的使用.
即使您设法通过二进制文件中的某种加密来保护字符串,您在某些时候也需要一个解密版本来执行.因此,在使用字符串的时间点创建内存转储也将包含秘密值的副本.这在Java中尤其成问题,因为您无法释放一块内存并且字符串是不可变的(意味着对字符串的"更改"将导致新的内存块).
如你所见,问题远非微不足道.当然,没有办法给你100%的安全性(想想所有破解的游戏等等).
可以以安全的方式实现的是使用公钥加密.在这种情况下,您需要隐藏私钥.如果您可以将内容发送到服务器以加密它们,或者您拥有提供可信平台模块的硬件,那么这可能是可能的.但那些事情可能不适合你的情况.
Mene的答案是正确的,但是我想用两分钱让你知道从编译后的二进制文件中提取字符串是多么的荒谬(无论语言如何).如果你有Linux,你所要做的就是运行命令strings <compiled binary>并获得提取的字符串.你不必成为任何逆向工程师来解决这个问题.我只是在我的Ubuntu机器上对着eclipse二进制文件运行它并查看(截断的)输出:
> strings eclipse
ATSH
0[A\
8.uCH
The %s executable launcher was unable to locate its
companion shared library.
There was a problem loading the shared library and
finding the entry point.
setInitialArgs
-vmargs
-name
--launcher.library
--launcher.suppressErrors
--launcher.ini
eclipse
Run Code Online (Sandbox Code Playgroud)
请注意字符串"%s可执行启动程序无法找到其随播共享库.加载共享库并找到入口点时出现问题." 出现在输出中.毫无疑问,这个字符串被硬编码到程序中.
当字符串(和其他数据)被硬编码到程序中时,大多数编译器将它们放入二进制文件中的特殊部分,它们可以直接映射到内存中,以便程序在需要时进行访问.如果您使用十六进制编辑器打开二进制文件,则可以轻松找到此字符串.