MSN Messenger:一个软件和一段代码
根据统计,MSN Messenger是国内使用率仅次于QQ的即时通信软件。不过MSN Messenger的登录方式显得有些怪异,而且它的本地密码存放机制也与QQ有所不同,它采用的是DPAPI加密方式(Data Protection API,一种数据保护接口,拥有两个函数用于提供系统级的数据保护服务),密码数据存储在注册表中。
要想找回MSN Messenger的密码,就得从注册表中提取出经过加密的数据。网上已经有开发高手写出来源程序:
#include
1<windows.h>
2
3#pragma comment(lib, "Advapi32.lib")
4#define FCHK(a) if (!(a)) {printf(#a " failed\n"); return 0;}
5typedef struct _CRYPTOAPI_BLOB {
6DWORD cbData;
7BYTE* pbData;
8} DATA_BLOB;
9typedef struct _CRYPTPROTECT_PROMPTSTRUCT {
10DWORD cbSize;
11DWORD dwPromptFlags;
12HWND hwndApp;
13LPCWSTR szPrompt;
14} CRYPTPROTECT_PROMPTSTRUCT, *PCRYPTPROTECT_PROMPTSTRUCT;
15typedef BOOL (WINAPI *PCryptUnprotectData)(
16DATA_BLOB* pDataIn,
17LPWSTR* ppszDataDescr,
18DATA_BLOB* pOptionalEntropy,
19PVOID pvReserved,
20CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct,
21DWORD dwFlags,
22DATA_BLOB* pDataOut
23);
24PCryptUnprotectData CryptUnprotectData = NULL;
25
26int main(void)
27{
28int ret;
29HMODULE hNtdll;
30HKEY hKey;
31DWORD dwType;
32char Data[0x100] = {0};
33DWORD dwSize;
34DATA_BLOB DataIn;
35DATA_BLOB DataOut;
36ret = RegOpenKeyEx
37(
38HKEY_CURRENT_USER,
39"Software\\\Microsoft\\\MSNMessenger",
400,
41KEY_READ,
42&hKey
43);
44if( ret != ERROR_SUCCESS ) return 1;
45ret = RegQueryValueEx
46(
47hKey,
48"Password.NET Messenger Service",
49NULL,
50&dwType,
51Data,
52&dwSize
53);
54if( ret != ERROR_SUCCESS ) return 1;
55FCHK ((hNtdll = LoadLibrary ("Crypt32.dll")) != NULL);
56FCHK ((CryptUnprotectData = (PCryptUnprotectData)
57GetProcAddress (hNtdll, "CryptUnprotectData")) != NULL);
58DataIn.pbData = Data + 2;
59DataIn.cbData = dwSize-2;
60CryptUnprotectData
61(
62&DataIn,
63NULL,
64NULL,
65NULL,
66NULL,
671,
68&DataOut
69);
70base64_decode (DataOut.pbData, Data, strlen(DataOut.pbData));
71printf ( "MSN Password: %s\n", Data);
72return 0;
73}
74//copied from GNU libc - libc/resolv/base64.c
75int base64_decode (char const *src, char *target, size_t targsize)
76{
77static const char Base64[] =
78"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
79static const char Pad64 = ‘=‘;
80int tarindex, state, ch;
81char *pos;
82state = 0;
83tarindex = 0;
84while ((ch = *src++) != ‘\0‘)
85{
86if (isspace (ch)) /* Skip whitespace anywhere. */
87continue;
88if (ch == Pad64)
89break;
90pos = strchr (Base64, ch);
91if (pos == 0) /* A non-base64 character. */
92return (-1);
93switch (state)
94{
95case 0:
96if (target)
97{
98if ((size_t) tarindex >= targsize)
99return (-1);
100target[tarindex] = (pos - Base64) << 2;
101}
102state = 1;
103break;
104case 1:
105if (target)
106{
107if ((size_t) tarindex + 1 >= targsize)
108return (-1);
109target[tarindex] |= (pos - Base64) >> 4;
110target[tarindex + 1] = ((pos - Base64) & 0x0f) << 4;
111}
112tarindex++;
113state = 2;
114break;
115case 2:
116if (target)
117{
118if ((size_t) tarindex + 1 >= targsize)
119return (-1);
120target[tarindex] |= (pos - Base64) >> 2;
121target[tarindex + 1] = ((pos - Base64) & 0x03) << 6;
122}
123tarindex++;
124state = 3;
125break;
126case 3:
127if (target)
128{
129if ((size_t) tarindex >= targsize)
130return (-1);
131target[tarindex] |= (pos - Base64);
132}
133tarindex++;
134state = 0;
135break;
136default:
137abort ();
138}
139}
140if (ch == Pad64)
141{ /* We got a pad char. */
142ch = *src++; /* Skip it, get next. */
143switch (state)
144{
145case 0: /* Invalid = in first position */
146case 1: /* Invalid = in second position */
147return (-1);
148case 2: /* Valid, means one byte of info */
149/* Skip any number of spaces. */
150for ((void) NULL; ch != ‘\0‘; ch = *src++)
151if (!isspace (ch))
152break;
153/* Make sure there is another trailing = sign. */
154if (ch != Pad64)
155return (-1);
156ch = *src++; /* Skip the = */
157/* Fall through to "single trailing =" case. */
158/* FALLTHROUGH */
159case 3: /* Valid, means two bytes of info */
160/*
161* We know this char is an =. Is there anything but
162* whitespace after it?
163*/
164for ((void) NULL; ch != ‘\0‘; ch = *src++)
165if (!isspace (ch))
166return (-1);
167if (target && target[tarindex] != 0)
168return (-1);
169}
170}
171else
172{
173if (state != 0)
174return (-1);
175}
176return (tarindex);
177}
178(该源程序版权归其原作者所有)
179
180如果你懂一些编译和Visual Studio知识,可以将它的执行文件写出来。</windows.h>