C++ 如何在 exe 或 dll 中隐藏字符串?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/926172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to hide strings in a exe or a dll?
提问by Winz
I discovered that it is possible to extract the hard-coded strings from a binary.
For example the properties view of Process Explorerdisplays all the string with more than 3 characters.
我发现可以从二进制文件中提取硬编码字符串。
例如,Process Explorer的属性视图显示所有超过 3 个字符的字符串。
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 simplyhide hiddenString1or hiddenString2in the executable?
- Is there a more secure way to use "cheat code" than with some obscure hidden input?
- 如何在可执行文件中简单地隐藏hiddenString1或hiddenString2?
- 有没有比使用一些晦涩的隐藏输入更安全的方法来使用“作弊代码”?
采纳答案by NotMe
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.
请记住,有些攻击比查看实际二进制文件更进一步。有时他们会在程序运行时调查程序的内存地址空间。MS在 .Net 2.0 中提出了一种叫做SecureString 的东西。目的是在应用程序运行时保持字符串加密。
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.
第四个想法是不要将字符串存储在应用程序本身中,而是依赖于提交到您控制的服务器的验证代码。在服务器上,您可以验证它是否是合法的“作弊代码”。
回答by Euro Micelli
There are many ways to obscuredata 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 impossibleto guaranteethat 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.
无论您使用多少加密或其他技巧;无论你投入多少精力或金钱。无论隐藏它涉及多少“NASA/MIT/CIA/NSA”类型。
It all comes down to simple physics:
If it were impossible for anyuser 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 hardto 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.
如果你有你的程序需要的真正关键的秘密信息,但永远不应该成为公开信息(比如私钥),那么你需要让你的程序与你控制的远程服务器通信,应用适当的身份验证和授权控制(也就是说,确保只有经过批准的人或计算机才能向服务器发出请求),并让该服务器保守秘密并使用它。
回答by Rob K
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.
最简单的方法是使用诸如 xor 或 rot-13 之类的小东西加密它们,然后在使用它们时即时解密它们。这将消除对它们的随意观看,但它不会阻止任何具有丰富倒车经验的人。
回答by Andre Miller
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.
除了 Chris 提到的那些方法之外,您还可以使用散列算法。如果您只想检查是否指定了正确的 ID,您实际上不需要在程序中存储整个 ID。
- Create a hash (MD5, SHA, etc) of the string/password/id you want to compare against, maybe add a 'salt' value to it. Store this in your program
- When the program is run, do the same algorithm on the input string/password/id and compare the two hashes to see if they match.
- 创建要与之比较的字符串/密码/id 的哈希(MD5、SHA 等),可能会为其添加“盐”值。将此存储在您的程序中
- 当程序运行时,对输入的字符串/密码/id 执行相同的算法,并比较两个哈希值是否匹配。
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.
这样,实际文本永远不会存储在您的程序中,并且他们无法对您的程序进行逆向工程以找出原始文本是什么,因为哈希算法只是单向的。
回答by CaffGeek
There are URLs for http requests that I would like to hide too.
还有一些我想隐藏的 http 请求的 URL。
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.
如果您的应用正在发出请求,则无需隐藏此请求。运行像 fiddler、http 分析器这样的应用程序,或者其他几十种免费且随时可用的方法中的一种,将显示您的应用程序产生的所有流量。
回答by Ian Boyd
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:
如果您不希望人们看到您的 GUID,则从字节构造它,而不是从字符串构造:
const GUID SecretGuid =
{ 0x4537774B, 0xCC80, 0x4eda, { 0x7A, 0x9E, 0xE7, 0x79, 0x91, 0xF5 } };
回答by Kevin Newman
Will all your secret codes be GUIDs or was that just an example?
你所有的密码都是 GUID 还是只是一个例子?
Perhaps store your secret as a binary guid:
也许将您的秘密存储为二进制 guid:
const GUID SecretGuid =
{ 0x4537774B, 0xCC80, 0x4eda, { 0x7A, 0x9E, 0xE7, 0x79, 0x91, 0xF5 } };
Then convert your supplied guid from string to binary format and compare the two binary guids.
然后将您提供的 guid 从字符串转换为二进制格式并比较两个二进制 guid。
回答by Michael Haephrati
Here is the method I use for this purpose. First, I use the the Stringstool by Sysinternalsto 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)
这是我用于此目的的方法。首先,我使用Sysinternals的Strings工具来显示 EXE 或 DLL 中的字符串。然后,我使用以下小工具(请参阅文章)将这些字符串替换为存储为算术表达式的乱码字符数组:例如:代替字符串: “这是一个测试”,我将放置以下代码:(由此工具自动生成)
WCHAR T1[28];
T1[22] = 69;
T1[15] = 121 - 17;
T1[9] = L':' + -26;
T1[12] = L't' - 1;
T1[6] = 116 - 1;
T1[17] = 117 - 12;
T1[3] = 116 - 1;
T1[14] = L'' - 3;
T1[13] = L'w' - 3;
T1[23] = 69;
T1[26] = L'Y' + 3;
T1[19] = 111 + 0;
T1[21] = L'k' - 34;
T1[27] = L'\' - 8;
T1[20] = L'B' + 32;
T1[4] = 42 + -10;
T1[25] = L'm' - 17;
T1[16] = L'H' + 18;
T1[18] = L'A' + 56;
T1[24] = 68;
T1[1] = 105 - 1;
T1[11] = L'k' - 6;
T1[10] = 66 + 50;
T1[2] = 105;
T1[0] = 117 - 1;
T1[5] = L'k' - 2;
T1[8] = 89 + 8;
T1[7] = 32;
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.
这个问题有很多解决方案,但没有一个(包括我的)是完美的,但是有一些方法可以打乱、伪装和隐藏敏感的字符串。您当然可以在运行时对它们进行加密和解密(请参阅本文),但我发现让这些字符串在可执行文件的位和字节中消失更重要,并且它可以工作。运行我的工具后,你不会在可执行文件中找到“这是一个测试”。
回答by suprit chaudhary
The best you can do is to code your password or other string that you want to hide as char array. For example:
您能做的最好的事情是将您想要隐藏的密码或其他字符串编码为字符数组。例如:
std::string s1 = "Hello"; // This will show up in exe in hex editor
char* s2 = "World"; // this will show up in exe in hex editor
char s3[] = {'G', 'O', 'D'}; // this will not show up in exe in hex editor.