001 #include <stdio.h>
002 #include <stdlib.h>
003 #include <windows.h>
004 #include <sys/stat.h>
005
006
007
008 #define VER "0.1"
009 #define FIND "Phrase" "x01x50"
010
011
012
013 typedef int (WINAPI*_steam_dll_pwd)(u_char *phrase, int len, void *boh);
014 _steam_dll_pwd steam_dll_pwd;
015 void std_err(void);
016
017
018
019 int main(int argc, char *argv[]) {
020 FILE *fd;
021 HINSTANCE hLib;
022 struct stat xstat;
023 u_int len;
024 u_short nlen;
025 u_char *buff,
026 *p,
027 *limit;
028
029 struct {
030 u_int boh1;
031 u_char *pass;
032 u_int boh2;
033 u_int boh3;
034 u_int boh4;
035 u_int passlen;
036 u_int boh5;
037 u_int boh6;
038 } steam_pwd;
039
040
041 setbuf(stdout, NULL);
042
043 fputs("n"
044 "Steam password decoder "VER"n"
045 "by Luigi Auriemman"
046 "e-mail: [email protected]"
047 "web: aluigi.orgn"
048 "n", stdout);
049
050 if(argc < 2) {
051 printf("n"
052 "Usage: %s <ClientRegistry.blob>n"
053 "n"
054 " NOTE: this password recovery tool works ONLY on the same computer in whichn"
055 " was located the ClientRegistry.blob file!n"
056 "n", argv[0]);
057 fputs("n Press RETURN to exitn", stdout);
058 fgetc(stdin);
059 exit(1);
060 }
061
062 printf("- load %s in memoryn", argv[1]);
063 fd = fopen(argv[1], "rb");
064 if(!fd) std_err();
065
066 fstat(fileno(fd), &xstat);
067 buff = malloc(xstat.st_size);
068 if(!buff) std_err();
069 fread(buff, xstat.st_size, 1, fd);
070 fclose(fd);
071
072 limit = buff + xstat.st_size - sizeof(FIND);
073 for(p = buff; p < limit; p++) {
074 if(!memcmp(p, FIND, sizeof(FIND) - 1)) break;
075 }
076
077 if(p < limit) {
078 p += 30;
079 nlen = *(u_short *)p;
080 p += 2;
081 len = *(u_int *)p;
082 p += 4 + nlen;
083
084 printf("nEncoded: %.*sn", len, p);
085
086 fputs("n- load the local STEAM.DLL file in memoryn", stdout);
087 hLib = LoadLibrary("STEAM.DLL");
088 if(!hLib) std_err();
089 steam_dll_pwd = (_steam_dll_pwd)0x20252397;
090
091 printf("n"
092 "NOTE: now if the tool crashes means the password cannot be recovered since then"
093 " ClientRegistry.blob file has not been created on this computer (Steamn"
094 " uses a ProductID based key).n");
095
096 memset(&steam_pwd, 0, sizeof(steam_pwd));
097 steam_dll_pwd(p, len, &steam_pwd);
098
099 printf("nPassword: %sn", steam_pwd.pass);
100 FreeLibrary(hLib);
101
102 } else {
103 printf("n"
104 "- Password not found, probably you have not saved it or have disabled then"
105 " storing of the local account informations through the Settings menu of Steamn");
106 }
107
108 free(buff);
109 fputs("n Press RETURN to exitn", stdout);
110 fgetc(stdin);
111 return(0);
112 }
113
114
115
116 void std_err(void) {
117 perror("nError");
118 fputs("n Press RETURN to exitn", stdout);
119 fgetc(stdin);
120 exit(1);
121 }
122
123
124 /*
125 This is the final part of the algorithm, I'm too lazy to implement
126 also the creation of the hash required for the decoding
127
128 u_char *steam_pwd(u_char *phrase) {
129 int i,
130 len;
131 static u_char *pwd;
132 u_char k[16],
133 *p,
134 al,
135 bl;
136
137 len = strlen(phrase) >> 1;
138 pwd = malloc(len + sizeof(char *)); // needed for direct sscanf
139 p = phrase;
140 for(i = 0; i < len; i++, p += 2) sscanf(p, "%02hhX", &pwd[i]);
141
142 memcpy(k, HASH + PRODUCTID, 16); // NOT implemented
143
144 for(i = 0; i < len; i++) {
145 bl = pwd[i];
146 al = k[i & 15];
147 k[i & 15] = bl;
148 pwd[i] = al ^ bl;
149 }
150 pwd[i] = 0;
151
152 return(pwd + (*pwd & 15) + 3);
153 }
154 */