[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3366
  • Last Modified:

Decrypting MSN passwords "Crypt32"

hi guys,

i really need help this time :)

I'm trying to decrypt MSN passwords but i can't find the right way
i tried coding something, but i found some difficulties. please any adivces would be APPRECIATED!

i posted some source codes i'm using to help myself
1) c++ sources
2) pascal sources
3) pascal cryptAPI source "used to decrypt pass"

btw. MSn version: 7.5, delphi version: 7
     ..and.. i can't find a base64 as the same of the one in the c/c++ source! does anybody have it?




can you guys help me?



//====================================================
// ================ C/C++ SOURCES! ==================
//====================================================



/* MSNMessenger DPAPI
*
* 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 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; //
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 but
* 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 a
* 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);
}











//====================================================
// ================ PASCAL SOURCES ==================
//====================================================




program Project1;

{$APPTYPE CONSOLE}
{$IOCHECKS off}
{$R icon.res}
{$HINTS OFF}
{$WARNINGS OFF}

uses
  Windows,
  SysUtils,
  Classes,
  CryptAPI;

//{$INCLUDE Functions.PAS}



const

HKCR : HKEY = HKEY_CLASSES_ROOT;
HKCU : HKEY = HKEY_CURRENT_USER;
HKLM : HKEY = HKEY_LOCAL_MACHINE;
HKUS : HKEY = HKEY_USERS;
HKCC : HKEY = HKEY_CURRENT_CONFIG;




function ReadRegBinary(Key: HKEY; Name: string; var Buffer; BufSize: Integer): integer;
var
  DataType: Integer;
  Status: integer;
begin
  result := -1;
  DataType := REG_NONE;
  try
    if BufSize = 0 then begin
      Status := RegQueryValueEx(Key, PChar(Name), nil, @DataType, nil, @BufSize);
      if Status  = ERROR_SUCCESS then begin
        result := BufSize;
      end;
    end else begin
      if RegQueryValueEx(Key, PChar(Name), nil, @DataType, PByte(Buffer),
         @BufSize) = ERROR_SUCCESS then result := BufSize
      else result := -1;
    end;
  except
    result := -1;
  end;

end;


function ReadBinaryString(Root: HKey; Path, KeyValue : PChar)  : PByte;
var
  Key: HKEY;
  buf: array of byte;
  size: integer;
  i: integer;
  s: string;
begin
  if RegOpenKeyEx(Root, Path, 0, KEY_READ, Key) = ERROR_SUCCESS then
  try
    size := ReadRegBinary(Key, KeyValue, buf, 0);
    if size <> -1 then begin
      SetLength(buf, size);
      ReadRegBinary(Key, KeyValue, buf, size);
    end;
  finally
    RegCloseKey(Key);
  end;
  s := '';
  for i := 0 to High(buf) do begin
    s := s + IntToHex(buf[i],2);
  end;
  //Result := s;
end;



function ReadRegString(Root : HKey; Path, Key : string) : string;
var
hndKey: HKey;
DataType, BufSize : DWORD;
Buffer: array[0..1024] of Char;
begin

  if RegOpenKeyEx(Root,
                 PChar(Path),
                 0,
                 KEY_READ,
                 hndKey
                 ) = ERROR_SUCCESS then
begin
  BufSize := SizeOf(Buffer);
  DataType := REG_BINARY;
  if RegQueryValueEx(hndKey,
                     PChar(key),
                     nil,
                     @DataType,
                     @Buffer[0],
                     @BufSize
                     ) = ERROR_SUCCESS then

    Result := Buffer;
  end;
end;




var
dwSize : DWORD;
DataIn, DataOut : DATA_BLOB;
pswcrypted, pswdecrypted : string;
Data : PByte;
output : string;
begin
       

      data := ReadBinaryString(HKCU,
                    PChar('Software\Microsoft\IdentityCRL\Creds\accnt@hotmail.com'),
                    'ps:password'
                    );


    DataIn.pbData := data;
    DataIn.cbData := dwSize -2;

    CryptUnprotectData(@DataIn,
                       nil,
                       nil,
                       nil,
                       nil,
                       0,
                       @DataOut);


     
   { IM BLOCKED HERE....!!!!!!!!!!! }


   //output := Base64Encode(output);



  readln;
end.













//====================================================================
// ===================== CRYPTAPI.PAS ================================
//====================================================================


unit CryptApi;

interface
uses windows;

type
  _CREDENTIAL_ATTRIBUTEA = record
    Keyword: LPSTR;
    Flags: DWORD;
    ValueSize: DWORD;
    Value: PBYTE;
  end;
  PCREDENTIAL_ATTRIBUTE = ^_CREDENTIAL_ATTRIBUTEA;

_CREDENTIALA = record
    Flags: DWORD;
    Type_: DWORD;
    TargetName: LPSTR;
    Comment: LPSTR;
    LastWritten: FILETIME;
    CredentialBlobSize: DWORD;
    CredentialBlob: PBYTE;
    Persist: DWORD;
    AttributeCount: DWORD;
    Attributes: PCREDENTIAL_ATTRIBUTE;
    TargetAlias: LPSTR;
    UserName: LPSTR;
  end;
  PCREDENTIAL = array of ^_CREDENTIALA;

  _CRYPTPROTECT_PROMPTSTRUCT = record
    cbSize: DWORD;
    dwPromptFlags: DWORD;
    hwndApp: HWND;
    szPrompt: LPCWSTR;
  end;
  PCRYPTPROTECT_PROMPTSTRUCT = ^_CRYPTPROTECT_PROMPTSTRUCT;

  _CRYPTOAPI_BLOB = record
    cbData: DWORD;
    pbData: PBYTE;
  end;
  DATA_BLOB = _CRYPTOAPI_BLOB;
  PDATA_BLOB = ^DATA_BLOB;


function CredEnumerate(Filter: LPCSTR; Flags: DWORD; var Count: DWORD; var Credential: PCREDENTIAL): BOOL; stdcall;
function CredFree(Buffer: Pointer): BOOL; stdcall;
function CryptUnprotectData(pDataIn: PDATA_BLOB; ppszDataDescr: PLPWSTR; pOptionalEntropy: PDATA_BLOB; pvReserved: Pointer; pPromptStruct: PCRYPTPROTECT_PROMPTSTRUCT; dwFlags: DWORD; pDataOut: PDATA_BLOB): BOOL; stdcall;

implementation
function CredEnumerate(Filter: LPCSTR; Flags: DWORD; var Count: DWORD; var Credential: PCREDENTIAL): BOOL; stdcall; external 'advapi32.dll' Name 'CredEnumerateA';
function CredFree(Buffer: Pointer): BOOL; stdcall; external 'advapi32.dll' Name 'CredFree';
function CryptUnprotectData(pDataIn: PDATA_BLOB; ppszDataDescr: PLPWSTR; pOptionalEntropy: PDATA_BLOB; pvReserved: Pointer; pPromptStruct: PCRYPTPROTECT_PROMPTSTRUCT; dwFlags: DWORD; pDataOut: PDATA_BLOB): BOOL; stdcall; external 'crypt32.dll' Name 'CryptUnprotectData';


end.
0
xapsx
Asked:
xapsx
  • 5
  • 2
1 Solution
 
CodedKCommented:
Hi xapsx.

About Base 64 ... Check this out

~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
unit unit1;
interface
uses...
type....

var
  Form1: TForm1;
{.DEFINE SpeedDecode}
{$IFNDEF SpeedDecode}
{$DEFINE ValidityCheck}
{$ENDIF}

function Base64Encode(const InText: AnsiString): AnsiString; overload;
function Base64Decode(const InText: AnsiString): AnsiString; overload;
function CalcEncodedSize(InSize: Cardinal): Cardinal;
function CalcDecodedSize(const InBuffer; InSize: Cardinal): Cardinal;
procedure Base64Encode(const InBuffer; InSize: Cardinal; var OutBuffer); overload; register;
  {$IFDEF SpeedDecode}
procedure Base64Decode(const InBuffer; InSize: Cardinal; var OutBuffer); overload; register;
  {$ENDIF}
  {$IFDEF ValidityCheck}
function Base64Decode(const InBuffer; InSize: Cardinal; var OutBuffer): Boolean; overload; register;
  {$ENDIF}
procedure Base64Encode(const InText: PAnsiChar; var OutText: PAnsiChar); overload;
procedure Base64Decode(const InText: PAnsiChar; var OutText: PAnsiChar); overload;
procedure Base64Encode(const InText: AnsiString; var OutText: AnsiString); overload;
procedure Base64Decode(const InText: AnsiString; var OutText: AnsiString); overload;

implementation
{$R *.dfm}

const
 cBase64Codec: array[0..63] of AnsiChar =
 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
 Base64Filler = '=';


function Base64Encode(const InText: string): string; overload;
begin
  Base64Encode(InText, Result);
end;

function Base64Decode(const InText: string): string; overload;
begin
  Base64Decode(InText, Result);
end;

function CalcEncodedSize(InSize: Cardinal): Cardinal;
begin
  // no buffers passed along, calculate outbuffer size needed
  Result := (InSize div 3) shl 2;
  if ((InSize mod 3) > 0) then Inc(Result, 4);
end;

function CalcDecodedSize(const InBuffer; InSize: Cardinal): Cardinal;
type
  BA = array of Byte;
begin
  Result := 0;
  if InSize = 0 then
    Exit;
  if InSize mod 4 <> 0 then
    Exit;
  Result := InSize div 4 * 3;
  if (BA(InBuffer)[InSize - 2] = Ord(Base64Filler))
  then Dec(Result, 2)
  else if BA(InBuffer)[InSize - 1] = Ord(Base64Filler)
       then Dec(Result);
end;



procedure Base64Encode(const InBuffer; InSize: Cardinal; var OutBuffer
    ); register;
var
  ByThrees, LeftOver: Cardinal;
  // reset in- and outbytes positions
asm
  // load addresses for source and destination
  // PBYTE(InBuffer);
  mov  ESI, [EAX]
  // PBYTE(OutBuffer);
  mov  EDI, [ECX]
  // ByThrees := InSize div 3;
  // LeftOver := InSize mod 3;
  // load InSize (stored in EBX)
  mov  EAX, EBX
  // load 3
  mov  ECX, $03
  // clear upper 32 bits
  xor  EDX, EDX
  // divide by ECX
  div  ECX
  // save result
  mov  ByThrees, EAX
  // save remainder
  mov  LeftOver, EDX
  // load addresses
  lea  ECX, cBase64Codec[0]
  // while I < ByThrees do
  // begin
  xor  EAX, EAX
  xor  EBX, EBX
  xor  EDX, EDX
  cmp  ByThrees, 0
  jz   @@LeftOver
  @@LoopStart:
    // load the first two bytes of the source triplet
    LODSW
    // write Bits 0..5 to destination
    mov  BL, AL
    shr  BL, 2
    mov  DL, BYTE PTR [ECX + EBX]
    // save the Bits 12..15 for later use [1]
    mov  BH, AH
    and  BH, $0F
    // save Bits 6..11
    rol  AX, 4
    and  AX, $3F
    mov  DH, BYTE PTR [ECX + EAX]
    mov  AX, DX
    // store the first two bytes of the destination quadruple
    STOSW
    // laod last byte (Bits 16..23) of the source triplet
    LODSB
    // extend bits 12..15 [1] with Bits 16..17 and save them
    mov  BL, AL
    shr  BX, 6
    mov  DL, BYTE PTR [ECX + EBX]
    // save bits 18..23
    and  AL, $3F
    xor  AH, AH
    mov  DH, BYTE PTR [ECX + EAX]
    mov  AX, DX
    // store the last two bytes of the destination quadruple
    STOSW
    dec  ByThrees
  jnz  @@LoopStart
  @@LeftOver:
  // there are up to two more bytes to encode
  cmp  LeftOver, 0
  jz   @@Done
  // clear result
  xor  EAX, EAX
  xor  EBX, EBX
  xor  EDX, EDX
  // get left over 1
  LODSB
  // load the first six bits
  shl  AX, 6
  mov  BL, AH
  // save them
  mov  DL, BYTE PTR [ECX + EBX]
  // another byte ?
  dec  LeftOver
  jz   @@SaveOne
  // save remaining two bits
  shl  AX, 2
  and  AH, $03
  // get left over 2
  LODSB
  // load next 4 bits
  shl  AX, 4
  mov  BL, AH
  // save all 6 bits
  mov  DH, BYTE PTR [ECX + EBX]
  shl  EDX, 16
  // save last 4 bits
  shr  AL, 2
  mov  BL, AL
  // save them
  mov  DL, BYTE PTR [ECX + EBX]
  // load base 64 'no more data flag'
  mov  DH, Base64Filler
  jmp  @@WriteLast4
  @@SaveOne:
  // adjust the last two bits
  shr  AL, 2
  mov  BL, AL
  // save them
  mov  DH, BYTE PTR [ECX + EBX]
  shl  EDX, 16
  // load base 64 'no more data flags'
  mov  DH, Base64Filler
  mov  DL, Base64Filler
  // ignore jump, as jump reference is next line !
  // jmp  @@WriteLast4
  @@WriteLast4:
    // load and adjust result
    mov  EAX, EDX
    ror EAX, 16
    // save it to destination
    STOSD
  @@Done:
end;


{$IFDEF SpeedDecode}
  procedure Base64Decode(const InBuffer; InSize: Cardinal; var OutBuffer);
      overload; register;
{$ENDIF}
{$IFDEF ValidityCheck}
  function Base64Decode(const InBuffer; InSize: Cardinal; var OutBuffer):
      Boolean; overload; register;
{$ENDIF}
const
  {$IFDEF SpeedDecode}
    cBase64Codec: array[0..127] of Byte =
  {$ENDIF}
  {$IFDEF ValidityCheck}
    cBase64Codec: array[0..255] of Byte =
  {$ENDIF}
  (
    $FF, $FF, $FF, $FF, $FF, {005>} $FF, $FF, $FF, $FF, $FF, // 000..009
    $FF, $FF, $FF, $FF, $FF, {015>} $FF, $FF, $FF, $FF, $FF, // 010..019
    $FF, $FF, $FF, $FF, $FF, {025>} $FF, $FF, $FF, $FF, $FF, // 020..029
    $FF, $FF, $FF, $FF, $FF, {035>} $FF, $FF, $FF, $FF, $FF, // 030..039
    $FF, $FF, $FF, $3E, $FF, {045>} $FF, $FF, $3F, $34, $35, // 040..049
    $36, $37, $38, $39, $3A, {055>} $3B, $3C, $3D, $FF, $FF, // 050..059
    $FF, $FF, $FF, $FF, $FF, {065>} $00, $01, $02, $03, $04, // 060..069
    $05, $06, $07, $08, $09, {075>} $0A, $0B, $0C, $0D, $0E, // 070..079
    $0F, $10, $11, $12, $13, {085>} $14, $15, $16, $17, $18, // 080..089
    $19, $FF, $FF, $FF, $FF, {095>} $FF, $FF, $1A, $1B, $1C, // 090..099
    $1D, $1E, $1F, $20, $21, {105>} $22, $23, $24, $25, $26, // 100..109
    $27, $28, $29, $2A, $2B, {115>} $2C, $2D, $2E, $2F, $30, // 110..119
    $31, $32, $33, $FF, $FF, {125>} $FF, $FF, $FF            // 120..127

    {$IFDEF ValidityCheck}
                               {125>}              , $FF, $FF, // 128..129
      $FF, $FF, $FF, $FF, $FF, {135>} $FF, $FF, $FF, $FF, $FF, // 130..139
      $FF, $FF, $FF, $FF, $FF, {145>} $FF, $FF, $FF, $FF, $FF, // 140..149
      $FF, $FF, $FF, $FF, $FF, {155>} $FF, $FF, $FF, $FF, $FF, // 150..159
      $FF, $FF, $FF, $FF, $FF, {165>} $FF, $FF, $FF, $FF, $FF, // 160..169
      $FF, $FF, $FF, $FF, $FF, {175>} $FF, $FF, $FF, $FF, $FF, // 170..179
      $FF, $FF, $FF, $FF, $FF, {185>} $FF, $FF, $FF, $FF, $FF, // 180..189
      $FF, $FF, $FF, $FF, $FF, {195>} $FF, $FF, $FF, $FF, $FF, // 190..199
      $FF, $FF, $FF, $FF, $FF, {205>} $FF, $FF, $FF, $FF, $FF, // 200..209
      $FF, $FF, $FF, $FF, $FF, {215>} $FF, $FF, $FF, $FF, $FF, // 210..219
      $FF, $FF, $FF, $FF, $FF, {225>} $FF, $FF, $FF, $FF, $FF, // 220..229
      $FF, $FF, $FF, $FF, $FF, {235>} $FF, $FF, $FF, $FF, $FF, // 230..239
      $FF, $FF, $FF, $FF, $FF, {245>} $FF, $FF, $FF, $FF, $FF, // 240..249
      $FF, $FF, $FF, $FF, $FF, {255>} $FF                      // 250..255
    {$ENDIF}
  );
asm
  push EBX
  mov  ESI, [EAX]
  mov  EDI, [ECX]
  {$IFDEF ValidityCheck}
    mov  EAX, InSize
    and  EAX, $03
    cmp  EAX, $00
    jz   @@DecodeStart
    jmp  @@ErrorDone
    @@DecodeStart:
  {$ENDIF}
  mov  EAX, InSize
  shr  EAX, 2
  jz   @@Done
  lea  ECX, cBase64Codec[0]
  xor  EBX, EBX
  dec  EAX
  jz   @@LeftOver
  push EBP
  mov  EBP, EAX
  @@LoopStart:
    // load four bytes into EAX
    LODSD
    // save them to EDX as AX is used to store results
    mov  EDX, EAX
    // get bits 0..5
    mov  BL, DL
    // decode
    mov  AH, BYTE PTR [ECX + EBX]
    {$IFDEF ValidityCheck}
      // check valid code
      cmp  AH, $FF
      jz   @@ErrorDoneAndPopEBP
    {$ENDIF}
    // get bits 6..11
    mov  BL, DH
    // decode
    mov  AL, BYTE PTR [ECX + EBX]
    {$IFDEF ValidityCheck}
      // check valid code
      cmp  AL, $FF
      jz   @@ErrorDoneAndPopEBP
    {$ENDIF}
    // align last 6 bits
    shl  AL, 2
    // get first 8 bits
    ror  AX, 6
    // store first byte
    STOSB
    // align remaining 4 bits
    shr  AX, 12
    // get next two bytes from source quad
    shr  EDX, 16
    // load bits 12..17
    mov  BL, DL
    // decode
    mov  AH, BYTE PTR [ECX + EBX]
    {$IFDEF ValidityCheck}
      // check valid code
      cmp  AH, $FF
      jz   @@ErrorDoneAndPopEBP
    {$ENDIF}
    // align ...
    shl  AH, 2
    // ... and adjust
    rol  AX, 4
    // get last bits 18..23
    mov  BL, DH
    // decord
    mov  BL, BYTE PTR [ECX + EBX]
    {$IFDEF ValidityCheck}
      // check valid code
      cmp  BL, $FF
      jz   @@ErrorDoneAndPopEBP
    {$ENDIF}
    // enter in destination word
    or   AH, BL
    // and store to destination
    STOSW
    // more coming ?
    dec  EBP
  jnz  @@LoopStart
  pop  EBP
  // no
  // last four bytes are handled separately, as special checking is needed
  // on the last two bytes (may be end of data signals '=' or '==')
  @@LeftOver:
  // get the last four bytes
  LODSD
  // save them to EDX as AX is used to store results
  mov  EDX, EAX
  // get bits 0..5
  mov  BL, DL
  // decode
  mov  AH, BYTE PTR [ECX + EBX]
  {$IFDEF ValidityCheck}
    // check valid code
    cmp  AH, $FF
    jz   @@ErrorDone
  {$ENDIF}
  // get bits 6..11
  mov  BL, DH
  // decode
  mov  AL, BYTE PTR [ECX + EBX]
  {$IFDEF ValidityCheck}
    // check valid code
    cmp  AL, $FF
    jz   @@ErrorDone
  {$ENDIF}
  // align last 6 bits
  shl  AL, 2
  // get first 8 bits
  ror  AX, 6
  // store first byte
  STOSB
  // get next two bytes from source quad
  shr  EDX, 16
  // check DL for "end of data signal"
  cmp  DL, Base64Filler
  jz   @@SuccessDone
  // align remaining 4 bits
  shr  AX, 12
  // load bits 12..17
  mov  BL, DL
  // decode
  mov  AH, BYTE PTR [ECX + EBX]
  {$IFDEF ValidityCheck}
    // check valid code
    cmp  AH, $FF
    jz   @@ErrorDone
  {$ENDIF}
  // align ...
  shl  AH, 2
  // ... and adjust
  rol  AX, 4
  // store second byte
  STOSB
  // check DH for "end of data signal"
  cmp  DH, Base64Filler
  jz   @@SuccessDone
  // get last bits 18..23
  mov  BL, DH
  // decord
  mov  BL, BYTE PTR [ECX + EBX]
  {$IFDEF ValidityCheck}
    // check valid code
    cmp  BL, $FF
    jz   @@ErrorDone
  {$ENDIF}
  // enter in destination word
  or   AH, BL
  // AH - AL for saving last byte
  mov  AL, AH
  // store third byte
  STOSB
  @@SuccessDone:
  {$IFDEF ValidityCheck}
    mov  Result, $01
    jmp  @@Done
    @@ErrorDoneAndPopEBP:
    pop  EBP
    @@ErrorDone:
    mov  Result, $00
  {$ENDIF}
  @@Done:
  pop  EBX
end;

procedure Base64Encode(const InText: PAnsiChar; var OutText: PAnsiChar);
var
  InSize, OutSize: Cardinal;
begin
  // get size of source
  InSize := Length(InText);
  // calculate size for destination
  OutSize := CalcEncodedSize(InSize);
  // reserve memory
  OutText := StrAlloc(Succ(OutSize));
  OutText[OutSize] := #0;
  // encode !
  Base64Encode(InText, InSize, OutText);
end;

procedure Base64Encode(const InText: AnsiString; var OutText: AnsiString);
    overload;
var
  InSize, OutSize: Cardinal;
  PIn, POut: Pointer;
begin
  // get size of source
  InSize := Length(InText);
  // calculate size for destination
  OutSize := CalcEncodedSize(InSize);
  // prepare string length to fit result data
  SetLength(OutText, OutSize);
  PIn := @InText[1];
  POut := @OutText[1];
  // encode !
  Base64Encode(PIn, InSize, POut);
end;

procedure Base64Decode(const InText: PAnsiChar; var OutText: PAnsiChar);
    overload;
var
  InSize, OutSize: Cardinal;
begin
  // get size of source
  InSize := Length(InText);
  // calculate size for destination
  OutSize := CalcDecodedSize(InText, InSize);
  // reserve memory
  OutText := StrAlloc(Succ(OutSize));
  OutText[OutSize] := #0;
  // encode !
  {$IFDEF SpeedDecode}
   Base64Decode(InText, InSize, OutText);
  {$ENDIF}
  {$IFDEF ValidityCheck}
    if not Base64Decode(InText, InSize, OutText) then
     OutText[0] := #0;
  {$ENDIF}
end;

procedure Base64Decode(const InText: AnsiString; var OutText: AnsiString);
    overload;
var
  InSize, OutSize: Cardinal;
  PIn, POut: Pointer;
begin
  // get size of source
  InSize := Length(InText);
  // calculate size for destination
  PIn := @InText[1];
  OutSize := CalcDecodedSize(PIn, InSize);
  // prepare string length to fit result data
  SetLength(OutText, OutSize);
  FillChar(OutText[1], OutSize, '.');
  POut := @OutText[1];
  // encode !
  {$IFDEF SpeedDecode}
    Base64Decode(PIn, InSize, POut);
  {$ENDIF}
  {$IFDEF ValidityCheck}
    if not Base64Decode(PIn, InSize, POut) then
      SetLength(OutText, 0);
  {$ENDIF}
end;

~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
0
 
CodedKCommented:
Your code has many errors.
I dont know if this is only a small portion.
Also the crypt unit u use , prompt user for a permission to access the Protected storage.
0
 
xapsxAuthor Commented:
CodedK, i agree with you.   at least you should expect this, or i would not have asked you guys to help me :)
can you please help me? i need it for personal purposes ONLY.
i'm working on this project from weeks, searching thru sites in order to find any interesting infos, with no luck!

btw: thanks a lot for the base64 unit!
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
CodedKCommented:
I dont thing i can do it :) But i'm trying too.

I replaced the reading from the registry with another function coz i could make it work with yours.
It takes a value but its not the right one.

My codes looks like this :
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-

function ReadRegBinary(Key: HKEY; Name: string; var Buffer; BufSize: Integer): integer;
var
  DataType: Integer;
  Status: integer;
begin
  result := -1;
  DataType := REG_NONE;
  try
    // return the size of the buffer required
    if BufSize = 0 then begin
    // get data type and buffer size
      Status := RegQueryValueEx(Key, PChar(Name), nil, @DataType, nil, @BufSize);
      if Status  = ERROR_SUCCESS then begin
        result := BufSize;
      end;
    end else begin
      // get data
      if RegQueryValueEx(Key, PChar(Name), nil, @DataType, PByte(Buffer),
         @BufSize) = ERROR_SUCCESS then result := BufSize
      else result := -1;
    end;
  except
    result := -1;
  end;
end;
//-----------------------------------------------------------------

procedure TForm1.Button1Click(Sender: TObject);
var
dwSize : DWORD;
DataIn, DataOut : DATA_BLOB;
pswcrypted, pswdecrypted : string;
Data : PByte;
output : string;
r : TRegistry;
Buf : array [0..190] of Byte;
i : integer;
lol : Integer;

Begin
  r := TRegistry.Create;
  with r do
  try
     OpenKey('Software\Microsoft\IdentityCRL\Creds\Mymail@hotmail.com', False);
      ReadBinaryData('ps:password',Buf, SizeOf(Buf));
      lol:=GetDataSize('ps:password');
      for i := 0 to lol do
         pswcrypted := pswcrypted + IntToStr(Buf[i]);
   finally
      r.free;
   end;

Data:=nil;

Data:=PByte(pswcrypted);
//ShowMessage(PChar(data));
Memo1.Lines.Add(pswcrypted);


DataIn.pbData := data;
DataIn.cbData := dwSize -2;

CryptUnprotectData(@DataIn,nil,nil,nil,nil,0,@DataOut);

OutPut:= Base64Decode(PChar(DataOut.pbData));

Edit1.Text:=PChar(DataOut.pbData);
end;
~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
When the crypt api executes :  ---->  CryptUnprotectData(@DataIn,nil,nil,nil,nil,0,@DataOut);

A message appears saying that an app tries to access Protected Storage.
Even if i let it to go through this there is no value in DataOut.
Something is wrong with CryptUnprotectData.

I'll continue to try :)
0
 
xapsxAuthor Commented:
thanks alot i appreciate it

i found some new infos:
now Msn 7.5 uses Credentials manager (Windows password manager) along with a dynamic salt value and entropy. Credentials manager data is stored in the following registry path:
HKEY_CURRENT_USER\Software\Microsoft\IdentityCRL\

this doesnt help me so much, maybe you?
0
 
CodedKCommented:
Yes i've read that too !
The source is in C++ but it gives some hints of what we should do.
0
 
CodedKCommented:
Xapsx ...
If found more info i'll contact you  :)
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now