看流星社区

 找回密码
 注册账号
查看: 2116|回复: 0

一个PsSetLoadImageNotifyRoutine回调内核注入DLL,支持xp ~ win7源码

[复制链接]

该用户从未签到

发表于 2017-6-1 17:25:30 | 显示全部楼层 |阅读模式
标 题: 【原创】一个PsSetLoadImageNotifyRoutine回调内核注入DLL,支持xp ~ win7源码
作 者: oxlwj
时 间: 2011-09-11,10:43:53
链 接: http://bbs.pediy.com/showthread.php?t=139986

一个PsSetLoadImageNotifyRoutine回调内核注入DLL,支持xp~win7源码

最近看sudimi大牛写的《一个有趣的内核注DLL的sys》文章,确实很有趣,可惜没开源,俺也写个,把完整代码也贴上来了,欢迎拍砖。


安装驱动,打开dbgview.exe,注入mydll.dll!!

VOIDStart(
INPUNICODE_STRINGFullImageName,
INHANDLEProcessId,//whereimageismapped
INPIMAGE_INFOImageInfo
)
{

NTSTATUSntStatus;
PIMAGE_IMPORT_DESCRIPTORpImportNew;

HANDLEhProcessHandle;
intnImportDllCount=0;

intsize;


//PID改变时,可以说明已经注入DLL了。
if(g_ulPid!=(ULONG)ProcessId&&g_ulPid!=0&&g_psaveDes!=NULL)
{
KAPC_STATEapcState;
BOOLEANbAttached=FALSE;

//_asmint3;

if(g_psaveDes!=NULL)
{
if(PsGetCurrentProcess()!=g_eprocess){
KeStackAttachProcess((PRKPROCESS)g_eprocess,&apcState);
bAttached=TRUE;
}

//
__asm{
cli;
moveax,cr0;
movoldCr0,eax;
andeax,not10000h;
movcr0,eax
}

//改导出表
pHeader->OptionalHeader.DataDirectory[1].Size-=sizeof(IMAGE_IMPORT_DESCRIPTOR);
pHeader->OptionalHeader.DataDirectory[1].VirtualAddress=(ULONG)g_psaveDes-ulBaseImage;

__asm{
moveax,oldCr0;
movcr0,eax;
sti;
}
g_psaveDes=NULL;

if(bAttached)
KeUnstackDetachProcess(&apcState);


}

return;
}
//注入进程没退出。
if(g_eprocess!=NULL)
return;

if(_stricmp(PsGetProcessImageFileName(PsGetCurrentProcess()),"dbgview.exe")==0)
{
//_asmint3;
g_eprocess=PsGetCurrentProcess();

g_ulPid=(ULONG)ProcessId;

ulBaseImage=(ULONG)ImageInfo->ImageBase;//进程基地址

pDos=(PIMAGE_DOS_HEADER)ulBaseImage;
pHeader=(PIMAGE_NT_HEADERS)(ulBaseImage+(ULONG)pDos->e_lfanew);
pImportDesc=(PIMAGE_IMPORT_DESCRIPTOR)((ULONG)pHeader->OptionalHeader.DataDirectory[1].VirtualAddress+ulBaseImage);



//导入DLL个数
nImportDllCount=pHeader->OptionalHeader.DataDirectory[1].Size/sizeof(IMAGE_IMPORT_DESCRIPTOR);

//把原始值保存。
g_psaveDes=pImportDesc;


ntStatus=ObOpenObjectByPointer(g_eprocess,OBJ_KERNEL_HANDLE,NULL,0x008,//PROCESS_VM_OPERATION
NULL,KernelMode,&hProcessHandle);

if(!NT_SUCCESS(ntStatus))
return;
//加上一个自己的结构。
size=sizeof(IMAGE_IMPORT_DESCRIPTOR)*(nImportDllCount+1);

//分配导入表
ntStatus=ZwAllocateVirtualMemory(hProcessHandle,&lpBuffer,0,&size,
MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if(!NT_SUCCESS(ntStatus)){
ZwClose(hProcessHandle);
return;
}
RtlZeroMemory(lpBuffer,sizeof(IMAGE_IMPORT_DESCRIPTOR)*(nImportDllCount+1));

size=20;
//分配当前进程空间。
ntStatus=ZwAllocateVirtualMemory(hProcessHandle,&lpDllName,0,&size,
MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if(!NT_SUCCESS(ntStatus)){

ZwClose(hProcessHandle);
return;
}
RtlZeroMemory(lpDllName,20);


/*分配导出函数的进程地址空间。
注意这里是分配高位地址的。如分配低位地址,得到PIMAGE_IMPORT_BY_NAME结构的地址会以,如ff等开头的负数地址,
这样,系统就会默认按序号查找API地址,会弹出找不到序号的框框。

*/
size=20;
ntStatus=ZwAllocateVirtualMemory(hProcessHandle,&lpExportApi,0,&size,
MEM_COMMIT|MEM_TOP_DOWN,PAGE_EXECUTE_READWRITE);
if(!NT_SUCCESS(ntStatus)){

ZwClose(hProcessHandle);
return;
}
RtlZeroMemory(lpExportApi,20);

//分配当前进程空间。
size=20;
ntStatus=ZwAllocateVirtualMemory(hProcessHandle,&lpTemp,0,&size,
MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if(!NT_SUCCESS(ntStatus)){

ZwClose(hProcessHandle);
return;
}
RtlZeroMemory(lpTemp,20);

//分配当前进程空间。
size=20;
ntStatus=ZwAllocateVirtualMemory(hProcessHandle,&lpTemp2,0,&size,
MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if(!NT_SUCCESS(ntStatus)){

ZwClose(hProcessHandle);
return;
}
RtlZeroMemory(lpTemp2,20);


pImportNew=lpBuffer;

//把原来数据保存好。
RtlCopyMemory(pImportNew+1,pImportDesc,sizeof(IMAGE_IMPORT_DESCRIPTOR)*nImportDllCount);


//构造自己的DLLIMAGE_IMPORT_DESCRIPTOR结构
{
IMAGE_IMPORT_DESCRIPTORAdd_ImportDesc;
PULONGulAddress;
ULONGoldCr0;
ULONGFunc;
PIMAGE_IMPORT_BY_NAMEptmp;
IMAGE_THUNK_DATA*pThunkData=(PIMAGE_THUNK_DATA)lpTemp2;


//_asmint3;
//
//ThunkData结构的地址
//
ptmp=(PIMAGE_IMPORT_BY_NAME)lpExportApi;
ptmp->Hint=0;
//至少要一个导出API
RtlCopyMemory(ptmp->Name,"ExportedFunction",18);

*(PULONG)lpTemp=(DWORD)ptmp-ulBaseImage;
pThunkData->u1.AddressOfData=(DWORD)ptmp-ulBaseImage;
//pThunkData[1].u1.AddressOfData=0;//导出函数截断
Add_ImportDesc.Characteristics=(DWORD)pThunkData-ulBaseImage;

Add_ImportDesc.TimeDateStamp=0;
Add_ImportDesc.ForwarderChain=0;

//
//DLL名字的RVA
//
RtlCopyMemory(lpDllName,"mydll.dll",20);
Add_ImportDesc.Name=(DWORD)lpDllName-ulBaseImage;
Add_ImportDesc.FirstThunk=Add_ImportDesc.Characteristics;


RtlCopyMemory(pImportNew,&Add_ImportDesc,sizeof(IMAGE_IMPORT_DESCRIPTOR));



__asm{
cli;
moveax,cr0;
movoldCr0,eax;
andeax,not10000h;
movcr0,eax
}

//改导出表
pHeader->OptionalHeader.DataDirectory[1].Size+=sizeof(IMAGE_IMPORT_DESCRIPTOR);
pHeader->OptionalHeader.DataDirectory[1].VirtualAddress=(ULONG)pImportNew-ulBaseImage;


__asm{
moveax,oldCr0;
movcr0,eax;
sti;
}

}
ZwClose(hProcessHandle);
hProcessHandle=NULL;
}
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 14:41

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表