第7章WinLogon编程(4)

2018-12-27 16:05

}

elseif(uMsg==WM_PAINT) {

RECTrect;

GetClientRect(hwndDlg,&rect); rect.top=rect.bottom-33;

DrawLogo(hwndDlg,IMAGE_FILE,rect.left,rect.top); }

returnbResult; }

BOOLWINAPIWlxInitialize(LPWSTRlpWinsta,HANDLEhWlx,PVOID pvReserved,PVOIDpWinLogonFunctions,PVOID*pWlxContext) {

g_pWinLogon=pWinLogonFunctions;

//NowhooktheWlxDialogBoxParam()dispatchfunction HookWlxDialogBoxParam(g_pWinLogon,g_dwVersion); returnpfWlxInitialize(lpWinsta,hWlx,pvReserved, pWinLogonFunctions,pWlxContext); }

注意这个函数也可以通过APIHOOK的方法拦截DialogBoxParam函数,达到同 样的目的。

如果用户希望能够屏蔽Ctrl+Alt+Del键,可以使用下面的代码: //当系统处于登录成功,没有锁定的状态下 //WinLogon接收到SAS事件,于是调用该函数 //现屏蔽所有事件,直接返回

intWINAPIWlxLoggedOnSAS(PVOIDpWlxContext,DWORDdwSasType,PVOID pReserved) {

returnWLX_SAS_ACTION_NONE; }

注意:

Windows只支持一个GINA动态链接库,用户编写发行的程序可能会被第三方编 写的GINA屏蔽,因为它们使用同样的注册表项。 7.4WinLogon进程的注入

WinLogon进程是一个十分重要的进程。实现这个进程的代码注入,可以获得用 户登录的的相关信息,实现与一个GINA动态链接库相同的功能。 实现WinLogon的进程注入的基本步骤如下。

(1)首先需要判断当前的操作系统是否是WindowsNT内核的系统,这里只支持 WindowsNT内核的系统。

BOOLIsWinNt(PDWORDpdwMajorVersion,PDWORDpdwMinorVersion) {

OSVERSIONINFOovi; DWORDlRet;

ovi.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);

lRet=GetVersionEx(&ovi); if(!lRet)

returnFALSE;

if(ovi.dwPlatformId!=VER_PLATFORM_WIN32_NT) returnFALSE;

*pdwMajorVersion=ovi.dwMajorVersion; *pdwMinorVersion=ovi.dwMinorVersion; returnTRUE; }

(2)为了实现系统进程的注入,用户必须得到调试权限。 BOOLGetDebugPriv(PTOKEN_PRIVILEGESptkpPrev) {

HANDLEhToken;

LUIDsedebugnameValue; TOKEN_PRIVILEGEStkp; BOOLbRet; ULONGulRet;

if(!OpenProcessToken(GetCurrentProcess(),

TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken)) returnFALSE;

bRet=LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&sedebugnameValue); if(!bRet) {

CloseHandle(hToken); returnbRet; }

tkp.PrivilegeCount=1;

tkp.Privileges[0].Luid=sedebugnameValue;

tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;

bRet=AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(tkp), ptkpPrev,&ulRet); CloseHandle(hToken); returnbRet; }

恢复原来的权限可以使用:

BOOLRestorePrivileges(TOKEN_PRIVILEGEStkp) {

HANDLEhToken; BOOLbRet;

if(!OpenProcessToken(GetCurrentProcess(),

TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken)) returnFALSE;

bRet=AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(tkp),NULL,N ULL);

CloseHandle(hToken); returnbRet; }

(3)实现对所有WinLogon进程实例的注入,其中入口参数为注入的动态链接库路径。 在注入实现中,程序主要调用了ntdll.dll输出的一个本机API函数

NtQuerySystemInformation,对系统中的所有进程进行枚举,只处理WinLogon进程,然 后调用LoadDllInProcessEx函数把注入动态链接库加载到WinLogon进程的地址空间。 在这个函数调用中用到了PPROCESSINFO和THREADINFO结构。结构定义如下: typedefstruct_tagThreadInfo {

FILETIMEftCreationTime; DWORDdwUnknown1; DWORDdwStartAddress; DWORDdwOwningPID; DWORDdwThreadID;

DWORDdwCurrentPriority; DWORDdwBasePriority; DWORDdwContextSwitches; DWORDdwThreadState; DWORDdwWaitReason; DWORDdwUnknown2[5];

}THREADINFO,*PTHREADINFO; #pragmawarning(disable:4200) typedefstruct_tagProcessInfo {

DWORDdwOffset;

DWORDdwThreadCount; DWORDdwUnknown1[6]; FILETIMEftCreationTime; DWORDdwUnknown2[5]; WCHAR*pszProcessName; DWORDdwBasePriority; DWORDdwProcessID;

DWORDdwParentProcessID; DWORDdwHandleCount; DWORDdwUnknown3; DWORDdwUnknown4;

DWORDdwVirtualBytesPeak; DWORDdwVirtualBytes; DWORDdwPageFaults;

DWORDdwWorkingSetPeak; DWORDdwWorkingSet; DWORDdwUnknown5; DWORDdwPagedPool;

DWORDdwUnknown6; DWORDdwNonPagedPool; DWORDdwPageFileBytesPeak; DWORDdwPrivateBytes; DWORDdwPageFileBytes; DWORDdwUnknown7[4]; THREADINFOti[0];

}_PROCESSINFO,*PPROCESSINFO;

ULONGInjectAllWinLogons(char*szDllPath) {PBYTEpbyInfo=NULL; DWORDcInfoSize=0x2000; ULONGret=0;

CHARszProcessName[PROCESS_SIZE]; PPROCESSINFOpProcessInfo; BOOLbLast;

DWORDdwResult=0;

if(!NtQuerySystemInformation)

NtQuerySystemInformation=(long(_stdcall*) (ULONG,PVOID,ULONG,ULONG))

GetProcAddress(GetModuleHandle(\\pbyInfo=(PBYTE)malloc(cInfoSize); if(pbyInfo) {

while(NtQuerySystemInformation(5,pbyInfo,cInfoSize,0)==STATUS_ INFO_LENGTH_MISMATCH) {

cInfoSize+=0x2000;

pbyInfo=(PBYTE)realloc(pbyInfo,cInfoSize); }

pProcessInfo=(PPROCESSINFO)pbyInfo; bLast=FALSE; do {

if(pProcessInfo->dwOffset==0)//last? bLast=TRUE;

if(pProcessInfo->dwProcessID!=0)//忽略systemidle {//convertprocessname

WideCharToMultiByte(CP_ACP,0,pProcessInfo->pszProcessName, -1,szProcessName,PROCESS_SIZE,NULL,NULL);

if(strnicmp(szProcessName,\{

printf(\\

//加载用户动态链接库到目标地址空间

if(dwResult=LoadDllInProcessEx(pProcessInfo->dwProcessID, szDllPath))

printf(\else

printf(\}

ret++; }

pProcessInfo=(PPROCESSINFO)((PBYTE)pProcessInfo+pProcessInfo->dw Offset);}

while(bLast==FALSE); free(pbyInfo); }

returnret; }

(4)代码的注入。实现代码注入的方法和以前注入是相似的,它采用了创建远程

线程的方法,其中dwPid是WinLogon进程的进程标识。函数首先调用OpenProcess 打开WinLogon进程的进程句柄,然后准备远程线程使用的数据结构,即初始化结构 成员。这些成员包含标志信息、模块句柄、路径信息、LdrLoadDll函数的地址等,然 后分三次注入到Winlogon进程中。运行后通过调用CreateRemoteThread启动远程线 程,读取线程运行结果。函数退出之前回收所有分配的资源。 DWORDLoadDllInProcessEx(DWORDdwPid,char*DllPathName) {

HANDLEhProcess,hThread; RemoteProcessDatarpd; PWSTRpwModuleFileName; HANDLEhModule=NULL; UNICODE_STRINGusModule; LPVOIDlpParameters,lpThread; SECURITY_ATTRIBUTESsaSecAttr; DWORDdwActual,dwResult=0,rc;

hProcess=OpenProcess(PROCESS_ALL_ACCESS,0,dwPid); if(hProcess==NULL)gotocleanup;

rpd.pLdrLoadDll=(LDRLOADDLL)GetProcAddress(GetModuleHandle(\\

if(!rpd.pLdrLoadDll)gotocleanup; rpd.Flags=0;

rpd.PathToFile=NULL; rpd.ModuleHandle=NULL;

pwModuleFileName=(PWSTR)malloc((strlen(DllPathName)*2)+1); if(!pwModuleFileName)gotocleanup;

MultiByteToWideChar(CP_ACP,0,DllPathName,strlen(DllPathName),pwModul eFileName,(strlen(DllPathName)*2)+1);


第7章WinLogon编程(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:20101014123937765《社会工作导论》试题及答案

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: