1

I am trying to get input from the user that the program will remember every time it runs. I want to do this in C. Based on my limited knowledge of computers, this will be stored in the storage/hard drive/ssd instead of the RAM/memory. I know I could use a database, or write to a text file, but I don't want to use an external file or a database, since I think that a database is a bit overkill for this and an external file can be messed with by the user. How can I do this (get the user to enter the input once and for the program to remember it forever)? Thanks! (If anyone needs me to clarify my question, I'd be happy to do so and when I get an answer, I will clarify this question for future users.)

Serket
  • 3,785
  • 3
  • 14
  • 45
  • Anything you need to store permanently on a user's PC can be messed with by the user. At most you can make it harder for them to mess with it by using operating system specific features – UnholySheep Apr 30 '20 at 21:08
  • Barring anything highly unusual and risky for system stability, you will need to create a file (or a database, which is eventually backed by files in the end). You can always place the file into a location that isn't easily reachable by a user by accident. – nanofarad Apr 30 '20 at 21:08
  • @nanofarad how do commercial programs do this? What file type do they use? – Serket Apr 30 '20 at 21:09
  • @nanofarad where can I place said file? – Serket Apr 30 '20 at 21:10
  • @UnholySheep what are these __operating system features__ you're talking about – Serket Apr 30 '20 at 21:10
  • 1
    @Serket They use whatever file format the devs wanted. You are writing a program, so you can create whatever logic you want to read/write from the file, such as text representations, serialization, protobuf, etc. You could place it into a hidden home directory on Linux or AppData on Windows. – nanofarad Apr 30 '20 at 21:10
  • @nanofarad which file types are the most common? – Serket Apr 30 '20 at 21:11
  • @Serket It depends on the type of program. A scientific processing application, web browser, and CAD program obviously have different storage requirements and as a result, different formats may be used. – nanofarad Apr 30 '20 at 21:12
  • 2
    [Hint](https://stackoverflow.com/q/2618188/2908724), then open your executable like it were a file, seek to that storage, and overwrite with the correct amount of padding and alignment. Malware often does something similar. – bishop Apr 30 '20 at 21:20
  • @bishop Thanks. This is exactly what I was looking for. I just have a few follow-up questions. 1. Can this be done to the executable that is currently running (can an executable do this to itself?) and 2. How can I implement this? (Btw if you write this as an answer, I will mark it as the correct answer and upvote it) – Serket Apr 30 '20 at 21:24
  • @bishop also, is there a specific name for this strategy of storing information? – Serket Apr 30 '20 at 21:30
  • Note that modifying the executable itself may set off antivirus software, and breaks any signature on the file. And if you are trying to prevent the user from easily messing with it, replacing the executable itself from backup or the original download may be one of the first things a casual user could try. – Arkku Apr 30 '20 at 21:33
  • 1. Depends upon the OS and the filesystem permissions of the executable. 2. I am refraining from answering because I think it shouldn't be done. :) I'd rather frame challenge: if the user running the program can modify the executable theu the program itself, they could modify it by hand outside the progeam. That is exactly the reason you don't want to use a separate file, so we are back to square one. IMO, the best balance is to have a separate file for ease of use by the program, but encode or encrypt it to keep casual users from tampering. – bishop Apr 30 '20 at 21:34
  • @bishop Sorry if I'm annoying you, I'm just new to low-level programming and CompSci ing general. I have 2 questions: 1. Why don't you think it should be done? 2. How can I encrypt a file? I always wanted to get into cybersecurity and cryptography, but I never knew where to start, so I'm wondering, would you be willing to put me on the right path (I only need you to answer the questions I asked above)? Thanks – Serket Apr 30 '20 at 21:41

4 Answers4

2

People have done this all kinds of ways. In order from best to worst (in my opinion):

  1. Use a registry or equivalent. That's what it's there for.
  2. Use an environment variable. IMO this is error prone and may not really be what you want.
  3. Store a file on your user's computer. Easy to do and simple.
  4. Store a file on a server and read/write to the server via the network. Annoying that you have to use the network, but OK.
  5. Modify your own binary on disk. This is fun as a learning experience, but generally inadvisable in production code. Still it can be done sometimes especially using an installer.
  6. Spawn a background process that "never" dies. This is strictly worse than using a file.
sudo rm -rf slash
  • 1,156
  • 2
  • 16
  • 27
  • How can I modify my own binary. Some guy named bishop also suggested this but I have no idea where to start. He also stated that a lot of malware use this method. – Serket Apr 30 '20 at 21:35
  • You *can* modify your binary by using `open`, `read`, and `write`. The hard part is finding which parts are safe to write to without messing up your program. It's going to depend a lot on your operating system. If you can use a better documented method like a registry you'll be better off. – sudo rm -rf slash Apr 30 '20 at 21:44
  • You said it'd be a fun learning experience, and it's kind of what I wanted to get out of this question. I'm up for the challenge of learning how to do it. Where can I start? – Serket Apr 30 '20 at 21:45
  • What operating system are you using? You'll want to find out the format of your executables and then look for a library that can parse those. For example on Windows you're looking for a PE modification library. I recommend pelib from Avast. – sudo rm -rf slash Apr 30 '20 at 21:48
  • I am on Mac. Is there a library you could recommend for parsing UNIX executables? – Serket Apr 30 '20 at 21:50
  • I have not used [LIEF](https://lief.quarkslab.com/doc/latest/getting_started.html#id1), but the documentation looks pretty good. – sudo rm -rf slash Apr 30 '20 at 21:52
1

You won't be able to prevent the user from modifying a file if they really want to. What you could do is create a file with a name or extension that makes it obvious that it should not be modified, or make it hidden to the user.

Alejandro De Cicco
  • 1,216
  • 3
  • 17
1

There isn't really any common way that you could write to a file and at the same time prevent the user from accessing it. You would need OS/platform level support to have some kind of protected storage.

The only real alternative commonly available is to store the information online on a server that you control and fetch it from there over the network. You could cache a cryptographically signed local copy with an expiration date to avoid having to connect every time the program is run. Of course if you are doing this as some kind of DRM or similar measure (e.g., time-limited demo), you will also need to protect your software from modification.

(Note that modifying the program itself, which you mentioned in a comment, is not really any different from modifying other files. In particular, the user can restore an earlier version of the program from backup or by re-downloading it, which is something even a casual user might try. Also, any signature on the software would become invalid by your modifications, and antivirus software may be triggered.)

If you simply wish to hide your file somewhere to protect against casual users (only), give it an obscure name and set the file hidden using both filesystem attributes and naming (in *nix systems with a . as the first character of file name). (How hidden you can make it may be thwarted by permissions and/or sandboxing, depending on the OS.)

Also note that if your goal is to hide the information from the user, you should encrypt it somehow. This includes any pieces of the data that are part of the program that writes it.

edit: In case I guessed incorrectly and the reason for wanting to do this is simply to keep things "clean", then just store it in the platform's usual "user settings" area. For example, AppData or registry on Windows, user defaults or ~/Library/Application Support on macOS, a "dotfile" on generic *nix systems, etc. Do not modify the application itself for this reason.

Arkku
  • 41,011
  • 10
  • 62
  • 84
0

If you want to persist data, the typical way to that is to store it to a file. Just use FILE* and go about your business.

Using a database for this may be an overkill, it depends on how you want to later access the data once it is stored.

If you just load the data from the file and search through it, then there is no need for a database, if you have loads of data and want to make complex searches, then a database is the way to go. If you need redundancy, user handling, security then choose a database, since the developers of each one already spent a lot of time fixing this.

halfer
  • 19,824
  • 17
  • 99
  • 186
AndersK
  • 35,813
  • 6
  • 60
  • 86