The meaning is as follows:

  1. There is a temporary buffer, the usual string, it gets a password.
  2. I need to clear all traces of this password so that those who are especially gifted cannot find it through the disassembler for example.

For example:

int main() { std::string str = { "Hello World!" }; printf_s("%s\n%#x", str.c_str(), &str); while (true) { Sleep(1); } return 0; } 

Open the well-known disassembler (if you can call it that) and open our process and search the string "Hello World!", We find the following:

enter image description here

Then the first thing that occurred to me was to use the SecureZeroMemory function.

We try:

 int main() { std::string str = { "Hello World!" }; printf_s("%s\n%#x", str.c_str(), &str); SecureZeroMemory(&str, str.capacity()); while (true) { Sleep(1); } return 0; } 

We repeat the manipulations with the disassembler, this is what it finds:

enter image description here

Already better, there are "2 findings" + one of these addresses, as I suppose the printf_s call, but the second base one did not get lost. Next, I used the fill algorithm, the result is the same.

Ultimately, I want to destroy all traces of the password so that lovers of reverse code could not find anything. Please suggest options.

  • That is, you want it to be stitched right into the code, and so that no one can find it? ... - Harry
  • @Harry - No, no, the password will go to the local variable, then I will send it to the server - then the contents of the local variable must be destroyed on the client application side. - Duracell
  • Well, erase the buffer where it is stored. You decided to wipe the place where the string is stored, and the buffer used by it, generally speaking, is far from there ... for example, walk the entire length of the string str , overwriting its characters with spaces. what you did, generally speaking, should crash the program in the end ... - Harry
  • @Harry - how to do it right? Well, for that I asked a question so that my mistakes would prompt me-) - Duracell
  • SecureZeroMemory(str.c_str(), str.length()); ? - Qwertiy

3 answers 3

One of the addresses is the initializing string literal "Hello World!" The second is the str string buffer.

Generally speaking, you need to wipe the string buffer, and you null a piece of memory in which the service information of the class object is stored - a pointer to the same buffer. And yet, with a long line - a bunch of other variables, for example, the contents of the stack or something else ... What you are doing will then come out sideways without fail.

You need to overwrite the string itself - type

 for(int i = 0; i < str.length(); ++i) str[i] = ' '; 

(I just don’t remember now whether it is possible by standard to access str.data() for writing).

Update So far, formally it is impossible, up to C ++ 17. So rub over the characters.

Update 2 And, so that when optimizing, the compiler does not see that the string is not used, and does not throw out the result, you need to work with it somehow.

Update 3 I did not say this :), but since the strings seem to be stored in all implementations in one piece in memory, you can play like this:

 SecureZeroMemory(&str[0], str.length()); 

only here the result is not formally guaranteed - it is necessary to check on a specific compiler.

Update 4 As I was told, the result is guaranteed :)

  • and something else to do with this line, so that the optimization does not throw out. - pavel
  • @pavel Yes, of course, you are right. - Harry
  • @Harry - I tried to overrun, this is what occurred to me in my first thoughts for (auto it: str) {it = ''; } - the result is similar to SecureZeroMemory - Duracell
  • @Duracell And it turns out quite differently: you get it in your cycle - just char , not a link to a character in a string, and you overwrite this local variable of the loop, that's all ... And not the string itself! - Harry
  • @Harry - -) And how can I wipe this line myself? - Duracell

Why don't you keep your password encrypted? To use it, you decrypt it, and then immediately delete it. You can find a decryption method that will do it in parts, i.e. in each unit of time you will have only one part of the password decrypted.

I do not know, of course, what program you are writing. But passwords are rarely stored in clear text. Usually stored password hash. For example MD5. And when a user enters a password, then the hash is also considered from him and hashes are compared, not passwords.

  • No, I need to remove it immediately - Duracell

Since I did not quite correctly ask the question, I will answer it myself. To remove a string literal, you need to search the string in the application module, find the static base address that contains the string literal, change the memory attributes so that you can overwrite the memory, and then reset the desired byte size.

  • Question one - why? :) If this line is just in the file. And if someone comes up with a disassembler, will he silently wait until the line is erased, and only then begin to work? :) - Harry
  • @Harry - well, why are there obfuscators, cryptors, etc. - Duracell
  • And this is what I said - "encrypt". Globally - to be honest, the idea seems to me dubious that a decent cracker, having a program in hand, will not find this same password ... - Harry
  • @Harry - I have one idea, I need to say thank you to you - suggested the idea of ​​encryption ... - Duracell