如何隐藏exe或dll中的字符串?
我发现可以从二进制文件中提取硬编码字符串。
例如,Process Explorer 的属性视图显示所有超过3 个字符。
这是我为了简单测试而编写的一个简单可执行文件的代码:
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
_TCHAR* hiddenString1 =_T("4537774B-CC80-4eda-B3E4-7A9EE77991F5");
_TCHAR* hiddenString2 =_T("hidden_password_or_whatever");
for (int i= 0; i<argc; i++) {
if (0 == _tcscmp(argv[i],hiddenString1)) {
_tprintf (_T("The guid argument is correct.\n")); }
else if (0 == _tcscmp(argv[i],hiddenString2)) {
_tprintf (_T("Do something here.\n")); }
}
_tprintf (_T("This is a visible string.\n"));
//Keep Running
Sleep(60000);
return 0;
}
可以清楚地从相应的可执行文件中提取字符串:
我认为找到字符串有点太容易了。
我的问题是:
- 如何简单隐藏hiddenString1或hiddenString2 可执行的?
- 有没有更安全的 使用“作弊代码”的方式比 一些晦涩的隐藏输入?
I discovered that it is possible to extract the hard-coded strings from a binary.
For example the properties view of Process Explorer displays all the string with more than 3 characters.
Here is the code of a simple executable that I wrote to simply test it:
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
_TCHAR* hiddenString1 =_T("4537774B-CC80-4eda-B3E4-7A9EE77991F5");
_TCHAR* hiddenString2 =_T("hidden_password_or_whatever");
for (int i= 0; i<argc; i++) {
if (0 == _tcscmp(argv[i],hiddenString1)) {
_tprintf (_T("The guid argument is correct.\n")); }
else if (0 == _tcscmp(argv[i],hiddenString2)) {
_tprintf (_T("Do something here.\n")); }
}
_tprintf (_T("This is a visible string.\n"));
//Keep Running
Sleep(60000);
return 0;
}
The strings can clearly be extracted from the corresponding executable:
I think that it is a little too easy to find the strings.
My questions are:
- How to simply hide hiddenString1 or hiddenString2 in the
executable? - Is there a more secure
way to use "cheat code" than with
some obscure hidden input?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
欢迎来到更广阔的防御性编程世界。
有几种选择,但我相信所有这些都依赖于某种形式的混淆; 尽管并不完美,但至少是一些东西。
您可以以其他二进制形式(十六进制?)存储文本,而不是直字符串值。
您可以加密存储在应用程序中的字符串,然后在运行时解密它们。
您可以将它们拆分到代码中的各个点,然后稍后重新构建。
或者它们的某种组合。
请记住,某些攻击比查看实际的二进制文件更进一步。 有时他们会在程序运行时调查程序的内存地址空间。 MS 在 .Net 2.0 中提出了一种名为 SecureString 的东西。 目的是在应用程序运行时保持字符串加密。
第四个想法是不要将字符串存储在应用程序本身中,而是依赖验证代码提交到您控制的服务器。 在服务器上您可以验证它是否是合法的“作弊代码”。
Welcome to the wider world of defensive programming.
There are a couple of options, but I believe all of them depend on some form of obfuscation; which, although not perfect, is at least something.
Instead of a straight string value you can store the text in some other binary form (hex?).
You can encrypt the strings that are stored in your app, then decrypt them at run time.
You can split them across various points in your code, and reconstitute later.
Or some combination thereof.
Bear in mind, that some attacks go further than looking at the actual binary. Sometimes they will investigate the memory address space of the program while it's running. MS came up with something called a SecureString in .Net 2.0. The purpose being to keep the strings encrypted while the app is running.
A fourth idea is to not store the string in the app itself, but rather rely on a validation code to be submitted to a server you control. On the server you can verify if it's a legit "cheat code" or not.
有很多方法可以隐藏可执行文件中的数据。 这里的其他人已经发布了很好的解决方案——有些比其他的更强大。 我不会添加到该列表中。
请注意:这都是一场猫捉老鼠的游戏:不可能要保证没有人会发现你的“秘密”。
无论您使用多少加密或其他技巧; 无论你付出多少努力或金钱。 无论有多少“NASA/MIT/CIA/NSA”类型参与隐藏它。
这一切都归结为简单的物理学:
如果任何用户都不可能从可执行文件中提取您的秘密并“取消隐藏”它,那么计算机也将无法取消隐藏它,并且您的程序将无法使用它。 任何具有足够动力的中等技能开发人员都会找到揭开秘密的方法。
当您将可执行文件交给用户时,他们就拥有了找出秘密所需的一切。
你所能期望的最好的结果就是让揭开这个秘密变得非常困难,以至于你从知道这个秘密中获得的任何好处都变得不值得这么麻烦。
因此,如果公开数据只是“不好”,或者公开的后果只是“不方便”,那么尝试掩盖数据是可以的。 但是,甚至不要考虑在程序中隐藏“主客户端数据库的密码”、私钥或其他一些关键秘密。 你就是不能。
如果您拥有真正的关键秘密信息,您的程序在某种程度上需要这些信息,但永远不应该成为公共信息(如私钥),那么您将需要让您的程序与您控制下的远程服务器进行通信,应用适当的身份验证和授权控制( 也就是说,确保只有经过批准的人员或计算机才能向服务器发出请求),并让该服务器保守秘密并使用它。
There are many ways to obscure data in an executable. Others here have posted good solutions -- some stronger than others. I won't add to that list.
Just be aware: it's all a cat-and-mouse game: it is impossible to guarantee that nobody will find out your "secret".
No matter how much encryption or other tricks you use; no matter how much effort or money you put into it. No matter how many "NASA/MIT/CIA/NSA" types are involved in hiding it.
It all comes down to simple physics:
If it were impossible for any user to pull out your secret from the executable and "unhide" it, then the computer would not be able to unhide it either, and your program wouldn't be able to use it. Any moderately skilled developer with enough incentive will find the way to unhide the secret.
The moment that you have handed your executable to a user, they have everything they need to find out the secret.
The best you can hope for is to make it so hard to uncover the secret that any benefits you can get from knowing the secret become not worth the hassle.
So, it's OK to try to obscure the data if it's merely "not-nice" for it to be public, or if the consequences of it becoming public would just be "inconvenient". But don't even think of hiding in your program "the password to your master client database", a private key, or some other critical secret. You just can't.
If you have truly critically secret information that your program will somehow need but should NEVER become public information (like a private key), then you will need to have your program talk to a remote server under your control, apply appropriate authentication and authorization controls (that is, make sure only the approved people or computers are able to make the request to the server), and have that server keep the secret and use it.
最简单的方法是使用 xor 或 rot-13 之类的简单方法对它们进行加密,然后在使用时即时解密。 这将消除随意观看它们的情况,但这不会阻止任何有丰富倒车经验的人。
The simplest way is to encrypt them with something trivial like xor or rot-13, and then decrypt them on the fly when they're used. That will eliminate casual viewing of them, but it won't stop anyone with much experience at reversing.
除了这些方法之外,克里斯提到您还可以使用哈希算法。 如果您只想检查是否指定了正确的 ID,则实际上不需要将整个 ID 存储在程序中。
这样,实际文本永远不会存储在您的程序中,并且他们无法对您的程序进行反向工程以找出原始文本是什么,因为哈希算法只是单向的。
In addition to those methods Chris mentions you could also use a hashing algorithm. If all you want to do is check if the correct ID was specified you don't actually need to store the whole ID in your program.
This way the actual text is never stored in your program and they cannot reverse engineer your program to find out what the original text was because hash algorithms are one-way only.
如果您的应用程序正在发出请求,则没有必要隐藏它。 运行 fiddler、http 分析器等应用程序或其他数十种免费且现成的方法之一将显示您的应用程序正在创建的所有流量。
If your app is making the request, there is no point hiding this. Running an app like fiddler, http analyzer, or one of dozens of other free and readily available methods will show all the traffic your app is creating.
您能做的最好的事情就是将您的密码或其他要隐藏的字符串编码为字符数组。 例如:
The best you can do is to code your password or other string that you want to hide as char array. For example:
这是我为此目的使用的方法。 首先,我使用 Strings 工具https://learn.microsoft.com/en-us/sysinternals/" rel="nofollow noreferrer">Sysinternals 显示 EXE 或 DLL 中的字符串。
然后,我使用以下小工具(请参阅article) 将这些字符串替换为存储为算术表达式的加扰字符数组:示例:代替字符串:
“这是一个测试”
我将放置以下代码:(由此工具自动生成)
这个问题有很多解决方案,但没有一个(包括我的)是完美的,但是有一些方法可以扰乱、伪装和隐藏敏感字符串。 您当然可以在运行时对它们进行加密和解密(请参阅本文),但我发现更重要的是使这些字符串在可执行文件的位和字节中消失并且它可以工作。 运行我的工具后,您不会在可执行文件中找到“这是一个测试”。
Here is the method I use for this purpose. First, I use the the Strings tool by Sysinternals to display the strings in an EXE or DLL.
I then use the following small tool (see article) to replace these strings with a scrambled array of characters stored as an arithmetic expression: for example: instead of the string:
"this is a test"
I will place the following code: (which is automatically generated by this tool)
There are many solutions to this problem and none of them (including mine) is perfect, however there are ways to scramble, disguise, and hide the sensitive strings. You can of course encrypt them and decrypt during runtime (see this article), but I find more important to make these string disappear among the bits and bytes of the executable file and it works. After running my tool, you won't find "this is a test" in the executable file.
您的所有密码都是 GUID 还是这只是一个示例?
也许将您的秘密存储为二进制 guid:
然后将提供的 guid 从字符串转换为二进制格式并比较两个二进制 guid。
Will all your secret codes be GUIDs or was that just an example?
Perhaps store your secret as a binary guid:
Then convert your supplied guid from string to binary format and compare the two binary guids.
如果您不希望人们看到某个特定字符串,请对其进行加密并在运行时解密。
如果您不希望人们看到您的 GUID,请从字节构造它,而不是从字符串构造:
If there's a specific string you don't want people to be able to see, then encrypt it and decrypt at runtime.
If you don't want people to see your GUID, then construct it from bytes, rather than constructed from a string: