I was playing with the CheatEngine and saw that it can view all my string in a client side application. I wonder what should I do to make the cheat engine not see my string at runtime. I tried every kind of approach that I knew, but whenever I have a string CheatEngine can view it. I would like to prevent this, or at least the CheatEngine visualize encrypted strings instead.
-
3Did you try to use `SecureString`? – Daniel A. White Dec 18 '14 at 13:46
-
Apart from the apparent lack of research effort, why the down- and close votes? I think it is a valid and interesting question. – CodeCaster Dec 18 '14 at 13:49
-
Using `SecureString` is possible, but it's *really* hard to do so. I've audited a lot of code that just plain did it wrong. You can't just magically protect a string in memory with it - it needs a secure source. – vcsjones Dec 18 '14 at 13:49
-
I tried that, but i need to convert back to string (for example to create a database conection string) and on this moment CheatEngine sees it again. – Flávio Dec 18 '14 at 13:51
-
What is the goal of encrypting strings? There may be a better approach to solve whatever you're trying to do. – Matthew Dec 18 '14 at 14:20
2 Answers
What you are asking for is very difficult to accomplish, correctly.
Many will point out that the SecureString
class can be used to keep strings that are in-memory safe. There are a lot of caveats to using a secure string.
- You need to create it securely. If you already have a
string
, you could just copy it into the SecureString by looping over each character. That doesn't accomplish anything though, because the original string is still there. It might get garbage collected later, but garbage collection does not mean the string's memory is zeroed. You could use unsafe code or platform invoke to zero a string in the CLR. However if your string is interned, you might end up breaking your program. - Let's say that you were able to create a
SecureString
securely, and ensure the source of the secure string is zeroed. You can't really do much with aSecureString
. Not of lot of APIs can do anything with them. At some point, you need to convert them back to a plain old string, use the string, and zero it. If the underlying API does anything insecure, like make a copy of it, then you won't be able to know where the copy is. And for that brief period of time where the plain old string exists in memory, an engine that is constantly monitoring your process's memory can grab it.
What I am really driving at here, is that protecting a process's memory from someone that has Administrative rights on the box is more-or-less impossible, and the .NET Framework complicates that matter. The CLR is designed to manage memory for you, which can run counter to your needs of explicit memory management.

- 138,677
- 31
- 291
- 286
-
Thank you @vcsjones! You gave me a direction. I could create a C++ unmanaged dll and treat the allocation and deallocation of memory manually (or zeroing the string) for some cases, like connectionstring creation. Not sure if it would work. But it may be a good approach. – Flávio Dec 18 '14 at 14:19
Try to use SecureString class !
Represents text that should be kept confidential. The text is encrypted for privacy when being used, and deleted from computer memory when no longer needed. This class cannot be inherited.

- 11,416
- 4
- 47
- 63
-
I seem to recall that SecureString is not actually secure - i.e. trivially available inspection tools will *automatically* obtain the decrypted text - hawkeye, etc – Marc Gravell Dec 18 '14 at 13:49
-
I tried that, but i need to convert back to string (for example to create a database conection string) and on this moment CheatEngine sees it again. – Flávio Dec 18 '14 at 13:50
-
@Flávio If you `dispose` your string just after you used it then i think cheat engine will have some pain to find it – Ludovic Feltz Dec 18 '14 at 13:52
-
-
-
@Ludovid, I tried that too, but for some reason the old one remains on memory. But now I'm in doubt if i did this the right way, i'll try it again. – Flávio Dec 18 '14 at 14:03
-
@Flávio `SecureString`, however, *is* `IDisposable`, and the `Dispose` method explicitly overwrites the contents with zeros: http://msdn.microsoft.com/en-us/library/system.security.securestring.dispose(v=vs.110).aspx – Marc Gravell Dec 18 '14 at 14:05
-
-
@MarcGravell I know that, but how can I create a database connection string without convert from SecureString to unsecure string? – Flávio Dec 18 '14 at 14:09
-
1@Flávio nope! you need the regular `string` for that - as `vcsjones` points out: you are very limited in terms of useful things you can do with a `SecureString`. – Marc Gravell Dec 18 '14 at 14:16