第7章WinLogon编程(5)

2018-12-27 16:05

usModule.Buffer=(PWSTR)InjectData(hProcess,pwModuleFileName,(strlen( DllPathName)*2)+1);

free(pwModuleFileName);

if(!usModule.Buffer)gotocleanup;

usModule.Length=(strlen(DllPathName)*2)+1;

usModule.MaximumLength=(strlen(DllPathName)*2)+1;

memcpy(&rpd.ModuleFileName,&usModule,sizeof(UNICODE_STRING)); lpParameters=InjectData(hProcess,&rpd,sizeof(RemoteProcessData)+4096 );

if(!lpParameters)gotocleanup;

lpThread=InjectData(hProcess,&RemoteThread,(PBYTE)EndRemoteThread-(P BYTE)RemoteThread+4096); if(!lpThread)gotocleanup; //Setsecurityattributes

saSecAttr.nLength=sizeof(SECURITY_ATTRIBUTES); saSecAttr.lpSecurityDescriptor=NULL; saSecAttr.bInheritHandle=TRUE;

hThread=CreateRemoteThread(hProcess,&saSecAttr,0,(LPTHREAD_START_ROU TINE)lpThread,lpParameters,0,&dwActual); if(hThread==NULL)gotocleanup;

rc=WaitForSingleObject(hThread,INFINITE); switch(rc) {

caseWAIT_TIMEOUT: break;

caseWAIT_FAILED: break;

caseWAIT_OBJECT_0:

if(ReadProcessMemory(hProcess,lpParameters,&rpd,sizeof (RemoteProcessData),&dwActual))

dwResult=(DWORD)rpd.ModuleHandle; break; default: break; }

cleanup:

if(rpd.ModuleFileName.Buffer!=NULL)

VirtualFreeEx(hProcess,rpd.ModuleFileName.Buffer, 0,MEM_RELEASE); if(lpParameters!=NULL)

VirtualFreeEx(hProcess,lpParameters,0,MEM_RELEASE); if(lpThread!=NULL)

VirtualFreeEx(hProcess,lpThread,0,MEM_RELEASE); if(hThread)CloseHandle(hThread);

if(hProcess)CloseHandle(hProcess); returndwResult; }

(5)远程线程代码的编写。远程线程代码主要是让Winlogon加载目标动态链接库, 加载的方法是调用NTDLL输出的LdrLoadDll函数。 NTSTATUS_stdcallRemoteThread(RemoteProcessData*rpd) {

NTSTATUSrc=(NTSTATUS)rpd->pLdrLoadDll(rpd->PathToFile, rpd->Flags,&rpd->ModuleFileName,&rpd->ModuleHandle); returnrc; }

void_stdcallEndRemoteThread(void){}

(6)注入代码的编写。注入代码和前面进程间代码注入采用的方法完全一样,通

过调用VirtualProtectEx函数在远程进程中分配地址空间,然后刷新缓存中的指令,最 后通过调用WriteProcessMemory函数实现数据的写入,这些数据包括远程线程代码和 数据参数。

LPVOIDInjectData(HANDLEhProcess,LPVOIDlpData,ULONGulFuncLen) {

LPVOIDlpAddress=NULL; DWORDdwOldProtect; DWORDBytesWritten=0;

//在远程进程中非数据分配内存

lpAddress=VirtualAllocEx(hProcess,NULL,ulFuncLen,MEM_COMMIT|MEM _TOP_DOWN,PAGE_EXECUTE_READWRITE); if(lpAddress) {

//改变分配内存的保护状态

if(VirtualProtectEx(hProcess,lpAddress,ulFuncLen, PAGE_EXECUTE_READWRITE,&dwOldProtect)) {

FlushInstructionCache(hProcess,lpAddress,ulFuncLen); //写数据到远程进程

if(WriteProcessMemory(hProcess,lpAddress, lpData,ulFuncLen,&BytesWritten)) {

//恢复原来的保护状态:)

VirtualProtectEx(hProcess,lpAddress,ulFuncLen,dwOldProtect,NULL); //返回数据的远程地址 returnlpAddress; }

//恢复原来的保护状态:)

VirtualProtectEx(hProcess,lpAddress,ulFuncLen,dwOldProtect,NULL); } }

return0; }

(7)到目前为止,目标动态链接库将开始运行,远程进程会首先调用动态链接库

的入口函数进行初始化。在这个代码中首先调用了InitHooks函数,初始化一个数据 结构,然后调用HookFunctionInCurrentProcess函数对当前进程实现API调用替换, 也就是我们说的函数拦截。

#defineWLXLOGGEDOUTHOOK0//#inhtHookTable struct{

char*dll;//DLL名称 char*func;//函数名称

LPVOIDppOriginal;//新地址 LPVOIDppHook;//旧地址 }htHookTable[]={

{\{NULL,NULL,NULL,NULL},//lastrecorddummy };

voidInitHooks(void)

{//\新地址

htHookTable[WLXLOGGEDOUTHOOK].ppHook=&NewWlxLoggedOutSAS; }

BOOLAPIENTRYDllMain(HINSTANCEhInst,DWORDdwReason,LPVOIDpvReserved) {

u_inti;

InitHooks();

switch(dwReason) {

caseDLL_PROCESS_ATTACH: i=0;

while(htHookTable[i].dll&&htHookTable[i].func) {

htHookTable[i].ppOriginal=HookFunctionInCurrentProcess(htHookTab le[i].dll,htHookTable[i].func,htHookTable[i].ppHook); i++; }

break;

caseDLL_PROCESS_DETACH: i=0;

//Unhook

while(htHookTable[i].dll&&htHookTable[i].func) {

UnHookFunctionInCurrentProcess(htHookTable[i].dll,htHookTable[i] .func,htHookTable[i].ppOriginal); i++; }

break; }

return1; }

(8)拦截代码的实现和前面介绍的Detours是一样的。首先它得到当前进程调用函 数的入口地址,保存起来,然后VirtualQuery函数查询和修改该地址的内存信息,对 该地址的入口指令进行替换,使其指向一个新的地址。这里使用了Z0MBiE提供的 LDE32库的disasm_main函数,这个函数能够得到一个指令的长度,它的作用在于保 证入口函数的开始指令长度大于5才能替换。这和Detours是一致的,用户可以参考 Detours实现的源程序。 #defineJMP0xE9//jmp #defineNOP0x90//nop

#defineJMP_SIZE5//jmpxxxxxxxxsize

#defineSTUB_SIZE0x10+JMP_SIZE//original\+jmp

VOIDBuildJMPBuffer(CHAR*pcJmpBuf,DWORDdwJmpAddr) {

pcJmpBuf[0]=(BYTE)JMP;

pcJmpBuf[1]=(BYTE)(dwJmpAddr&0xFF);

pcJmpBuf[2]=(BYTE)((dwJmpAddr>>8)&0xFF); pcJmpBuf[3]=(BYTE)((dwJmpAddr>>16)&0xFF); pcJmpBuf[4]=(BYTE)((dwJmpAddr>>24)&0xFF); }

//这个函数在给定函数的入口地址处填写了一个jmp指令,然后返回原来函数的入口地址 LPVOIDHookFunctionInCurrentProcess(LPCSTRcsModuleName,LPCSTR csFunctionName,LPVOIDlpJmpAddress) {

LPVOIDlpModule,lpFunction,lpStub=NULL;

DWORDdwOldProtect,dwBytesWritten,dwBytesRead,dwLength=0; MEMORY_BASIC_INFORMATIONmbi; CHARcStub[STUB_SIZE]; CHAR*cJmpFunction; CHAR*pReadAddress; INTs;

HANDLEhProcess=GetCurrentProcess(); BOOLbWrite,bRead; //得到模块地址

lpModule=GetModuleHandleA(csModuleName); if(!lpModule) returnNULL; //得到函数地址

lpFunction=GetProcAddress(lpModule,csFunctionName); if(!lpFunction)returnNULL; //获得函数地址的内存信息

VirtualQuery(lpFunction,&mbi,sizeof(MEMORY_BASIC_INFORMATION)); //修改内存区域的保护属性

VirtualProtect(mbi.BaseAddress,mbi.RegionSize,PAGE_EXECUTE_READWRITE ,&mbi.Protect);

//使用nop指令添加代理入口地址 FillMemory(cStub,STUB_SIZE,NOP); pReadAddress=lpFunction;

//读取第一条汇编指令的长度,Z0MBiE在LDE32中提供 s=disasm_main(pReadAddress); while(s!=-1&&dwLength

dwLength+=s; pReadAddress+=s;

s=disasm_main(pReadAddress);//下一条指令的长度 }

//函数代码太短,无法完成

if(dwLength

//读取函数的前几个指令到代理缓冲区

bRead=ReadProcessMemory(hProcess,lpFunction,cStub,dwLength,&dwBytesR ead);

if(!bRead||dwBytesRead!=dwLength)gotoprotect;

lpStub=VirtualAlloc(NULL,STUB_SIZE,MEM_COMMIT|MEM_TOP_DOWN,PAGE_ READWRITE);

if(!lpStub)gotoprotect;

BuildJMPBuffer(cStub+(STUB_SIZE-JMP_SIZE),((DWORD)lpFunction+dwLengt h)-((DWORD)lpStub+(STUB_SIZE)));

bWrite=WriteProcessMemory(hProcess,lpStub,cStub,STUB_SIZE,&dwBytesWr itten);

if((!bWrite)||(dwBytesWritten!=STUB_SIZE))gotofree;

VirtualProtect(lpStub,STUB_SIZE,mbi.Protect,&dwOldProtect); cJmpFunction=(CHAR*)malloc(dwLength); FillMemory(cJmpFunction,dwLength,'\\0');

BuildJMPBuffer(cJmpFunction,(DWORD)lpJmpAddress-(DWORD)lpFunction- JMP_SIZE)

bWrite=WriteProcessMemory(hProcess,lpFunction,cJmpFunction,dwLength, &dwBytesWritten); free(cJmpFunction);

if(!bWrite||dwBytesWritten!=dwLength) {

if(dwBytesWritten)

WriteProcessMemory(hProcess,lpFunction,lpStub,dwBytesWritten, &dwBytesWritten); gotofree; }


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

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

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

马上注册会员

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