Skip to content

Commit a2cbdcd

Browse files
committed
Rewrite README for a general audience
Lead with the problem a player actually has, add download badges and a release link, a step-by-step quick start, a troubleshooting table, and move the crypto and build details below the usage sections.
1 parent 0c4c707 commit a2cbdcd

1 file changed

Lines changed: 146 additions & 108 deletions

File tree

‎README.md‎

Lines changed: 146 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,135 @@
11
# RE4SaveIdFinder
22

3-
Recovers the **Steam32 ID** that a Resident Evil 4 Remake save file was signed with, when
4-
you no longer know it — and then re-signs your saves for whichever account you play on now.
3+
**Moves a Resident Evil 4 Remake save to another Steam account — even when you have no idea
4+
which account it came from.**
55

6-
RE4R saves (`data*.bin`, DSSS/"Lime" format) are encrypted against the Steam ID of the
7-
account that wrote them. To move a save to another account it has to be re-signed — but that
8-
needs the *original* ID as input. Normally you read it from the save's folder name
9-
(`Steam\userdata\<steam32>\2050650\...`). If all you have is a loose `.bin` — a backup
10-
from a dead PC, a save someone sent you, a cracked install whose config is gone — that ID
11-
is unrecoverable by inspection. **It is not stored anywhere in the file.**
6+
[![Download](https://img.shields.io/badge/Download-Windows%20x64-blue)](https://github.com/DrSaeedHub/RE4SaveIdFinder/releases/latest)
7+
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
128

13-
This tool finds it by testing every possible ID, fast enough to be practical: the entire
14-
32-bit space in about **7 minutes**.
15-
16-
It is a single self-contained Windows `.exe`. Double-click it for the desktop app; run it
17-
with arguments for the original command-line scanner.
9+
One file. No installer, no .NET runtime, no setup. Double-click it and you get a window;
10+
run it from a terminal and you get the command-line scanner.
1811

1912
---
2013

21-
## Quick start (no technical knowledge needed)
14+
## What problem does this solve?
15+
16+
RE4R saves are locked to the Steam account that created them. To play a save on a different
17+
account it has to be **re-signed**, and re-signing needs the *original* account's ID as input.
18+
19+
Normally you just read that ID off the folder name:
20+
21+
```
22+
Steam\userdata\<this number is the ID>\2050650\remote\win64_save\data001Slot.bin
23+
```
24+
25+
But if all you have is a loose `.bin` — a backup off a dead hard drive, a save a friend sent
26+
you, a cracked install whose folders are long gone — that number is **gone for good**. It is
27+
not written anywhere inside the file.
2228

23-
1. Double-click `RE4SaveIdFinder.exe`. A window opens with three things it can do.
24-
2. **Find the Steam ID** — click *Choose a save file...* (or drag a save onto the window),
25-
then press **Start**. Leave it running; it finds the account the save belongs to.
26-
3. **Re-sign saves** — pick the folder your saves are in, put the ID it just found in the
27-
first box and your own Steam ID in the second, then press *Re-sign the ticked files*.
28-
Copies of your originals are always kept.
29-
4. Copy the re-signed saves into your own account's save folder and play.
29+
So this tool simply tries every account number there is. All 4,294,967,295 of them, in about
30+
**7 minutes**.
3031

31-
Your saves live in
32-
`Steam\userdata\<number>\2050650\remote\win64_save`.
32+
## Get it
33+
34+
1. **[Download the latest release](https://github.com/DrSaeedHub/RE4SaveIdFinder/releases/latest)**
35+
(`RE4SaveIdFinder-win-x64.zip`) and unzip it anywhere.
36+
2. Double-click `RE4SaveIdFinder.exe`.
37+
38+
Windows may warn about an unrecognised app the first time — that is SmartScreen reacting to a
39+
new, unsigned executable, not a virus report. Choose *More info → Run anyway* if you trust the
40+
download.
3341

3442
---
3543

36-
## The three screens
44+
## Quick start
3745

38-
### 1. Find the Steam ID
46+
> **Goal:** take a save that belongs to some unknown account and make it yours.
47+
48+
1. **Find out who owns the save.** On the *Find the Steam ID* screen, choose your `.bin` file
49+
(or drag it onto the window) and press **Start**. Go make coffee — it takes a few minutes
50+
and tells you when it is done.
51+
2. **Re-sign it.** Press the button that jumps you to the *Re-sign saves* screen with the
52+
found ID already filled in. Pick the folder your saves are in, put **your own** Steam ID in
53+
the second box, tick the files you want, press *Re-sign the ticked files*.
54+
3. **Put them back.** Copy the re-signed files into your own save folder:
55+
`Steam\userdata\<your number>\2050650\remote\win64_save`
56+
4. Play.
3957

40-
Point it at one save file. It shows the file name, size, and whether it really is a
41-
Resident Evil save, then searches every possible account number for the one that opens it.
42-
While it runs you get a progress bar, a percentage, the speed in IDs per second, elapsed
43-
time and an estimate of the time left, plus a log of what it is doing.
58+
Your originals are always backed up first, so step 2 cannot lose anything.
4459

45-
- **Pause / Resume / Stop** at any time. Pause and Stop take effect at the end of the piece
46-
of work already under way (a few seconds; adjustable in Settings).
47-
- When it finds the answer it shows both forms of the ID — Steam32 and SteamID64
48-
(`76561197960265728 + steam32`) — each with a **Copy** button, and offers a one-click jump
49-
to the re-sign screen with the ID already filled in.
50-
- An advanced option lets you search only part of the range if you already know roughly
51-
where to look. Most people should leave it alone.
60+
**Don't know your own Steam ID?** It is the folder name under `Steam\userdata\`. If there is
61+
more than one folder there, the one containing a `2050650` subfolder is your RE4R account.
62+
The app also accepts the long 17-digit `SteamID64` form and converts it for you.
63+
64+
**You only need to search once.** Every save written by the same account shares the same ID —
65+
find it on one file, then re-sign the whole folder in one go.
66+
67+
---
5268

53-
Any one save file works: every file written by the same account shares one ID, so search the
54-
smallest and re-sign the rest.
69+
## The app, screen by screen
70+
71+
### 1. Find the Steam ID
72+
73+
Point it at one save file. It shows the file name, size, and confirms the file really is a
74+
Resident Evil save before it starts. While it runs you get a progress bar, percentage, speed
75+
in IDs per second, elapsed time, an estimate of the time remaining, and a running log.
76+
77+
- **Pause**, **Resume** and **Stop** any time. They take effect at the end of the piece of
78+
work already under way — a few seconds.
79+
- **Nothing is lost if you close it.** Progress is saved every few seconds. Reopen the same
80+
save later — even renamed, even moved to a different folder — and the app offers to pick up
81+
where it left off. That includes after a crash or a force-kill, which is exactly when you
82+
want it most.
83+
- When it finds the answer it shows both forms of the ID (Steam32 and SteamID64), each with a
84+
**Copy** button, plus a one-click jump to the re-sign screen.
85+
- An advanced option can search only part of the range if you already know roughly where to
86+
look. Most people should leave it alone.
5587

5688
### 2. Re-sign saves
5789

58-
Pick the folder holding your saves. Every `*.bin` in it is listed with a tick box, so you can
59-
leave any of them alone. Then give it two IDs:
90+
Pick the folder holding your saves. Every `*.bin` in it is listed with a tick box. Then give
91+
it two IDs:
6092

61-
- **Saves belong to** — the ID the saves are signed with now. Press *Work it out for me* to
62-
run the same search as screen 1 on the first ticked file.
93+
- **Saves belong to** — the ID they are signed with now. Press *Work it out for me* to run
94+
the search from screen 1 on the first ticked file.
6395
- **Move them to** — the account that will play them.
6496

65-
Either box accepts the short (Steam32) or long (SteamID64) form; a long one is converted
66-
automatically. Each file is then re-signed, and the per-file outcome appears in the list.
97+
Either box takes the short (Steam32) or long (SteamID64) form. Each file is re-signed and its
98+
result appears next to it in the list.
6799

68-
What it guarantees:
100+
Three guarantees:
69101

70-
- **Every original is backed up first** — into a `backup_<timestamp>` subfolder, or as a
71-
`.bak` next to the file, depending on the setting. Backups are never overwritten.
72-
- **A file is only replaced once the new bytes have been proven to decrypt** with the new
73-
ID. The new version is written to a temporary file and moved into place only after that
74-
check passes.
75-
- **One bad file never stops the batch.** If a save is not signed with the ID you gave, it is
102+
- **Every original is backed up first**, into a `backup_<timestamp>` subfolder or as a `.bak`
103+
beside the file (your choice in Settings). Backups are never overwritten.
104+
- **A file is only replaced after the new bytes are proven to decrypt** with the new ID. The
105+
new version is written to a temporary file and moved into place only once that check passes.
106+
- **One bad file never stops the batch.** A save that is not signed with the ID you gave is
76107
reported as failed, left exactly as it was, and the rest carry on.
77108

78109
### 3. Check a single ID
79110

80-
You already have an ID in mind and just want to know whether a save belongs to it. Choose the
81-
file, type the ID, press **Check**. The answer is instant and uses the full-decryption
82-
proof — not the quick 4-byte test — so a "MATCH" is a real match.
111+
You already have an ID in mind and want to know whether a save belongs to it. Choose the file,
112+
type the ID, press **Check**. Instant, and it uses the full-decryption proof rather than the
113+
quick 4-byte test — so a "MATCH" is a real match.
114+
115+
---
116+
117+
## Troubleshooting
118+
119+
| What you see | What it means |
120+
| --- | --- |
121+
| "Not a valid encrypted save" | The file is not an encrypted DSSS/Lime save. Wrong file, or already decrypted. The tool refuses rather than search meaningless data. |
122+
| The search finishes with no result | The save was not written by any Steam account ID — most likely it is not an RE4R save, or it has been modified by another tool. |
123+
| Re-signing reports a file as failed | That file is not signed with the ID in the *Saves belong to* box. It was left untouched; run a search on that specific file. |
124+
| The game does not see the re-signed save | Check the destination path is `...\userdata\<your id>\2050650\remote\win64_save`, and that Steam Cloud has not overwritten it — start the game offline once, or disable cloud sync for RE4R while you swap saves. |
125+
| The app will not open a second window | By design: one copy per machine. Starting a second brings the existing window to the front. |
126+
| Something crashed | Full details are appended to `%APPDATA%\RE4SaveIdFinder\last-error.log`. Quote it in a bug report. |
83127

84128
---
85129

86130
## Command line
87131

88-
The same `.exe`, run with arguments, behaves exactly as it always did:
132+
The same `.exe`, run with arguments, is the original scanner:
89133

90134
```
91135
RE4SaveIdFinder <input.bin> # scan all 4.29 billion IDs (~7 min)
@@ -109,26 +153,26 @@ SteamID64 : 76561199918786219
109153

110154
Exit codes: `0` found · `1` not found · `2` bad input (including `--help`) · `3` self-test failed.
111155

112-
The app is a Windows GUI executable, so it has no console of its own. On the command-line
113-
path it attaches to the console that started it; if you redirect its output to a file or a
114-
pipe, that redirection is left untouched. Running it with no arguments opens the desktop app.
156+
The app is a Windows GUI executable, so it has no console of its own. On the command-line path
157+
it attaches to the console that started it; redirecting output to a file or pipe is left
158+
untouched. Running it with no arguments opens the desktop app.
115159

116160
The command-line path never reads or writes the settings file and never takes the
117161
single-instance lock, so scripts and CI keep working while the window is open.
118162

119163
---
120164

121-
## Settings, saved progress, single instance
165+
## Where it keeps things
122166

123167
Everything the app remembers lives under `%APPDATA%\RE4SaveIdFinder` — never next to the
124-
`.exe`, so the executable stays portable.
168+
`.exe`, so the executable stays portable. Delete that folder and you are back to defaults.
125169

126-
### `%APPDATA%\RE4SaveIdFinder\config.ini`
170+
### `config.ini`
127171

128-
Plain INI text with a comment header; safe to edit in Notepad, and safe to delete (the
129-
defaults come back). Any value that is missing, unreadable or out of range falls back to its
130-
default rather than upsetting the app. Settings are written as they change, not only on a
131-
tidy exit, so a crash or a force-kill does not lose them.
172+
Plain INI text with a comment header; safe to edit in Notepad, safe to delete. Any value that
173+
is missing, unreadable or out of range falls back to its default rather than upsetting the
174+
app. Settings are written as they change, not only on a tidy exit, so a crash does not lose
175+
them.
132176

133177
| Key | Meaning |
134178
| --- | --- |
@@ -147,48 +191,40 @@ tidy exit, so a crash or a force-kill does not lose them.
147191
allows: one logical processor is always reserved so the machine stays responsive during a
148192
search. A larger number in the ini is ignored in favour of the default.
149193

150-
If the app ever fails with an error message, the full details are appended to
151-
`%APPDATA%\RE4SaveIdFinder\last-error.log` — worth quoting in a bug report.
152-
153-
### `%APPDATA%\RE4SaveIdFinder\jobs\<sha256>.json`
194+
### `jobs\<sha256>.json`
154195

155196
An unfinished search is remembered under the **SHA-256 of the save file's contents**, so
156197
picking the same save from a different folder — or after renaming it — finds the same
157-
progress. Each file records the hash, original path, file size, the range, the chunk size,
158-
the set of completed chunks (and the contiguous high-water mark), the raw candidates found so
159-
far, the thread count, UTC ISO-8601 start and last-updated timestamps, and the status
198+
progress. Each file records the hash, original path, file size, the range, the chunk size, the
199+
completed chunks (and the contiguous high-water mark), the raw candidates found so far, the
200+
thread count, UTC ISO-8601 start and last-updated timestamps, and the status
160201
(`running` / `paused` / `completed`).
161202

162-
Progress is written every few seconds and on pause, stop and exit, so a crash or a kill
163-
costs seconds of work rather than minutes. A chunk is recorded **only after its scan has
164-
returned**, so resuming can never skip a range that was not actually searched.
165-
166-
When you choose a save that has unfinished progress, the app asks - there and then, as soon
167-
as you pick the file - whether to **Resume** or **Start over**, showing how far it got and
168-
how long ago. This does not depend on the app having been closed tidily: a search that was
169-
interrupted by a crash or a force-kill is still marked `running` in its job file, and is
170-
offered back exactly the same way, because that is precisely when the work is worth most.
171-
A finished search is marked `completed` and never prompts again — it just shows the answer it found. *Clear saved progress* on the search
172-
screen forgets one save; *Forget all saved progress* in Settings clears the lot.
203+
A chunk is recorded **only after its scan has returned**, so resuming can never skip a range
204+
that was not actually searched. A finished search is marked `completed` and never prompts
205+
again — it just shows the answer it found. *Clear saved progress* on the search screen forgets
206+
one save; *Forget all saved progress* in Settings clears the lot.
173207

174208
### One window at a time
175209

176210
The desktop app takes a named `Global\` mutex, so only one copy runs per machine. Start a
177-
second one and the window you already have is brought to the front instead; if Windows
178-
refuses that, the second copy says so briefly and exits. An abandoned mutex (from a previous
179-
crash) is taken over cleanly, and if the global name cannot be created at all the app falls
180-
back to a per-session lock rather than refusing to start.
211+
second and the existing window is brought to the front; if Windows refuses that, the second
212+
copy says so briefly and exits. An abandoned mutex from a previous crash is taken over
213+
cleanly, and if the global name cannot be created at all the app falls back to a per-session
214+
lock rather than refusing to start.
181215

182216
---
183217

184-
## Why it is fast
218+
## How it works
185219

186-
LimebrellaSharpCore's own `LimepickSegmentBatch` computes `Header^(~id) mod privateKey1`
187-
for each candidate — a full modular exponentiation, about **512 IDs/s**. At that rate the
188-
full space takes roughly **74 hours**.
220+
### Why it is fast
189221

190-
The exponent is `~id`, which for a 32-bit id is exactly `2^64 - 1 - id`. So as the
191-
candidate rises by one, the exponent falls by one:
222+
LimebrellaSharpCore's own `LimepickSegmentBatch` computes `Header^(~id) mod privateKey1` for
223+
each candidate — a full modular exponentiation, about **512 IDs/s**. At that rate the full
224+
space takes roughly **74 hours**.
225+
226+
The exponent is `~id`, which for a 32-bit id is exactly `2^64 - 1 - id`. So as the candidate
227+
rises by one, the exponent falls by one:
192228

193229
```
194230
result(id+1) = result(id) · Header⁻¹ (mod n)
@@ -198,24 +234,26 @@ Scanning a contiguous range therefore needs **one** modular exponentiation up fr
198234
single modular multiply per candidate after that. Measured **~620× faster**: 10.4M IDs/s
199235
across 31 threads.
200236

201-
## Correctness
237+
### Why the answer is trustworthy
202238

203239
The inner test compares only 4 bytes of decrypted output, so it collides by chance roughly
204-
once per 2^32 candidates — a full scan typically yields several hits, most of them wrong.
205-
A real scan of one save produced 4 candidates and **only 1 was genuine**.
240+
once per 2^32 candidates — a full scan typically yields several hits, most of them wrong. A
241+
real scan of one save produced 4 candidates and **only 1 was genuine**.
206242

207243
Every candidate is therefore confirmed by decrypting the whole file and validating its
208-
checksum. Only a candidate that passes is reported, in the GUI exactly as on the command
209-
line. A tool that stops at the first 4-byte match will hand you a wrong ID with no indication
210-
anything went wrong.
244+
checksum. Only a candidate that passes is reported, in the app exactly as on the command line.
245+
*A tool that stops at the first 4-byte match will hand you a wrong ID with no indication
246+
anything went wrong.*
211247

212-
On startup the fast path is also cross-checked against the library on known IDs; on any
248+
On startup the fast path is cross-checked against the library on known IDs; on any
213249
disagreement the tool refuses to scan (exit code 3, or a plain-language dialog in the app)
214250
rather than produce a wrong answer.
215251

216-
A file is only accepted if it really parses as an encrypted DSSS save. The library will
217-
otherwise happily treat any file as raw plaintext, which would send the search off across
218-
meaningless data.
252+
A file is only accepted if it really parses as an encrypted DSSS save. The library would
253+
otherwise happily treat any file as raw plaintext and send the search off across meaningless
254+
data.
255+
256+
---
219257

220258
## Requirements
221259

@@ -261,13 +299,13 @@ showing anything. Any exception fails the run and prints the type, message and s
261299
## Credits
262300

263301
Save format handling and all cryptography by
264-
[LimebrellaSharp](https://github.com/mi5hmash/LimebrellaSharp) by Michał Gębicki (MIT) —
265-
see `THIRD-PARTY-NOTICES.txt`. This tool only makes searching for an unknown ID practical,
266-
and wraps the whole job in a desktop app.
302+
[LimebrellaSharp](https://github.com/mi5hmash/LimebrellaSharp) by Michał Gębicki (MIT) — see
303+
`THIRD-PARTY-NOTICES.txt`. This tool only makes searching for an unknown ID practical, and
304+
wraps the whole job in a desktop app.
267305

268306
## License
269307

270308
MIT — see [LICENSE](LICENSE).
271309

272-
Bundles [LimebrellaSharp](https://github.com/mi5hmash/LimebrellaSharp) (MIT), whose notice
273-
is reproduced in `THIRD-PARTY-NOTICES.txt`.
310+
Bundles [LimebrellaSharp](https://github.com/mi5hmash/LimebrellaSharp) (MIT), whose notice is
311+
reproduced in `THIRD-PARTY-NOTICES.txt`.

0 commit comments

Comments
 (0)