- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
标 题: 【原创】一个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;
} |
|