⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 在驱动层启动应用层的程序.txt

📁 文件系统驱动开发的文档资料(IFS DDK)
💻 TXT
📖 第 1 页 / 共 2 页
字号:
能否在驱动层启动应用层的程序?

能否在驱动层启动应用层的程序?

====================================

完全可以,其实就和远线程一样.找到一个进程的EPROCESS和ETHREAD,然后把你要执行的代码影射到该进程中,然后设置该线程的USERAPCPENDING状态,然后KEINITIALAPC,初始化我们APC,KEINSERTQUEUEAPC将我们的APC插入到目标线程的APC队列,然后等待执行即可..... 
//Say welcome to usermode calls in kernel land..... with this technique you can even call MessageBox from inside your driver. 
//No more ugly non-working phrack samples, this is the real stuff :) 

NTKERNELAPI 
VOID 
KeInitializeApc ( 
IN PRKAPC Apc, 
IN PKTHREAD Thread, 
IN KAPC_ENVIRONMENT Environment, 
IN PKKERNEL_ROUTINE KernelRoutine, 
IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, 
IN PKNORMAL_ROUTINE NormalRoutine OPTIONAL, 
IN KPROCESSOR_MODE ApcMode, 
IN PVOID NormalContext 
); 

// note some texts give this as void?? (and will link as such) 
BOOLEAN 
KeInsertQueueApc( 
PKAPC Apc, 
PVOID SystemArgument1, 
PVOID SystemArgument2, 
UCHAR mode); // guessing this is Kernel, User, 
// or Maximum (0,1,2) 
// 11/24/03 - Albert Almeida [AA] 
// gives this last param as 
// IN KPRIORITY Increment 

1) The APC injector 

//************************************************************************ 
// NTSTATUS UtilInstallUserModeApcForCreateProcess(char* CommandLine, PKTHREAD pTargetThread, PKPROCESS pTargetProcess) 
// 
// Setup usermode APC to execute a process 
//************************************************************************/ 
NTSTATUS UtilInstallUserModeApcForCreateProcess(char* CommandLine, PKTHREAD pTargetThread, PEPROCESS pTargetProcess) 
{ 
PRKAPC pApc = NULL; 
PMDL pMdl = NULL; 
PVOID MappedAddress = NULL; 



ULONG size; 
KAPC_STATE ApcState; 
PKEVENT pEvent = NULL; 

// check params 
if (!pTargetThread || !pTargetProcess) 
return STATUS_UNSUCCESSFUL; 

// allocate memory for apc and event 
pApc = ExAllocatePool (NonPagedPool,sizeof (KAPC)); 
if (!pApc) 
return STATUS_INSUFFICIENT_RESOURCES; 

pEvent = ExAllocatePool (NonPagedPool,sizeof (KEVENT)); 
if (!pEvent) 
{ 
ExFreePool (pApc); 
return STATUS_INSUFFICIENT_RESOURCES; 
} 

// allocate mdl big enough to map the code to be executed 
size = (unsigned char*)UtilUserApcCreateProcessEnd - (unsigned char*)UtilUserApcCreateProcess; 
pMdl = IoAllocateMdl (UtilUserApcCreateProcess, size, FALSE,FALSE,NULL); 
if (!pMdl) 
{ 
ExFreePool (pEvent); 
ExFreePool (pApc); 
return STATUS_INSUFFICIENT_RESOURCES; 
} 

// lock the pages in memory 
__try 
{ 
MmProbeAndLockPages (pMdl,KernelMode,IoWriteAccess); 
} 
__except (EXCEPTION_EXECUTE_HANDLER) 
{ 
IoFreeMdl (pMdl); 
ExFreePool (pEvent); 
ExFreePool (pApc); 
return STATUS_UNSUCCESSFUL; 
} 

// map the pages into the specified process 
KeStackAttachProcess (pTargetProcess,&ApcState); 
MappedAddress = MmMapLockedPagesSpecifyCache (pMdl,UserMode,MmCached,NULL,FALSE,NormalPagePriority); 

if (!MappedAddress) 
{ 
// cannot map address 
KeUnstackDetachProcess (&ApcState); 
IoFreeMdl (pMdl); 
ExFreePool (pEvent); 
ExFreePool (pApc); 
return STATUS_UNSUCCESSFUL; 
} 

// copy commandline 
if(CommandLine) 
{ 
memset ((unsigned char*)MappedAddress + 160, 0, 260); 
memcpy ((unsigned char*)MappedAddress + 160, CommandLine,strlen (CommandLine)); 
} 

KeUnstackDetachProcess (&ApcState); 

// initialize apc 
KeInitializeEvent(pEvent,NotificationEvent,FALSE); 
KeInitializeApc(pApc,pTargetThread, OriginalApcEnvironment,&UtilUserApcCreateProcessKernelRoutine, 
NULL, MappedAddress, UserMode, (PVOID) NULL); 

// schedule apc 
if (!KeInsertQueueApc(pApc,pEvent,NULL,0)) 
{ 
// failed apc delivery 
MmUnlockPages(pMdl); 
IoFreeMdl (pMdl); 
ExFreePool (pEvent); 
ExFreePool (pApc); 
return STATUS_UNSUCCESSFUL; 
} 

// and fire it by manually alerting the thread (for reference, this set the KTHREAD.ApcState.KernelApcInProgress) 
// beware, this could be not compatible with everything ..... it works on 2k/XP anyway, tested on SP2 too..... 
*((unsigned char *)pTargetThread+0x4a)=1; 

// apc is fired, wait event to signal completion 
KeWaitForSingleObject (pEvent,Executive,KernelMode,FALSE,NULL); 

// free event 
ExFreePool (pEvent); 

// unmap and unlock pages / mdl . Note that there's no need to call MmUnmapLockedPages on paged locked with MmProbeAndLockPages, 
// since MmUnlockPages does this for us automatically. 
MmUnlockPages(pMdl); 
IoFreeMdl (pMdl); 

return STATUS_SUCCESS; 
} 

2) This routine just frees the APC allocated memory as soon as it's fired 

//************************************************************************ 
// VOID UtilUserApcCreateProcessKernelRoutine( IN struct _KAPC *Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, 
// IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2 ) 
// 
// This routine just frees the APC 
//************************************************************************/ 
VOID UtilUserApcCreateProcessKernelRoutine( IN struct _KAPC *Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, 
IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2 ) 
{ 
PKEVENT pEvent; 

KDebugPrint (1,("%s APC KernelRoutine called, freeing APC.\n", MODULE)); 

// free apc 
ExFreePool(Apc); 

// set event to signal apc execution 
pEvent = (PKEVENT)*SystemArgument1; 
KeSetEvent (pEvent,IO_NO_INCREMENT,FALSE); 
} 

3) This is the usermode routine launched by the APC. It gets Kernel32 base and find imports by a hash, then calls winexec (simpler 
than call createprocess, but anyway this is just an example....). 

Use this NASM macro to calculate the needed hashes for whatever usermode functions you may need to call : 

; 
; HASH - NASM macro for calculating win32 symbol hashes 
; Usage: HASH instruction, 'SymbolName' 
; 
%macro HASH 2 
%assign i 1 ; i = 1 
%assign h 0 ; h = 0 
%strlen len %2 ; len = strlen(%2) 
%rep len 
%substr char %2 i ; fetch next character 
%assign h \ 
(h<<0x13) + \ 
(h>>0x0d) + \ 
char ; rotate and add 
%assign i i+1 ; increment i 
%endrep 
%1 h ; return instruction with hash 
%endmacro 

I can't remember where i got this shellcode, it was lying already modified on my hd for long time. Anyway it's not mine.... 
i just rearranged it to my needs. Whoever recognizes it as his code, email me at valeryno@hotmail.com and i'll put the proper credits :) 

//************************************************************************ 
// void UtilUserApcCreateProcess(PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2) 
// 
// This is where we call createprocess. We're in usermode here :) 
//************************************************************************/ 
__declspec(naked) void UtilUserApcCreateProcess(PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2) 
{ 
__asm 
{ 
push ebp 
mov ebp,esp 
push ebx 
push esi 
push edi 
jmp __startup; ; these are just functions.... skip 

__find_kernel32: 
push esi ; Save esi 
push 0x30 
pop ecx 
mov eax, fs:[ecx] ; Extract the PEB 
mov eax, [eax + 0x0c] ; Extract the PROCESS_MODULE_INFO pointer from the PEB 
mov esi, [eax + 0x1c] ; Get the address of flink in the init module list 
lodsd ; Load the address of blink into eax 
mov eax, [eax + 0x8] ; Grab the module base address from the list entry 
pop esi ; Restore esi 
ret ; Return 

__find_function: 
pushad ; Save all registers 
mov ebp, [esp + 0x24] ; Store the base address in eax 
mov eax, [ebp + 0x3c] ; PE header VMA 
mov edx, [ebp + eax + 0x78] ; Export table relative offset 
add edx, ebp ; Export table VMA 
mov ecx, [edx + 0x18] ; Number of names 
mov ebx, [edx + 0x20] ; Names table relative offset 
add ebx, ebp ; Names table VMA 

__find_function_loop: 
jecxz __find_function_finished ; Jump to the end if ecx is 0 
dec ecx ; Decrement our names counter 
mov esi, [ebx + ecx * 4] ; Store the relative offset of the name 
add esi, ebp ; Set esi to the VMA of the current name 

xor edi, edi ; Zero edi 
xor eax, eax ; Zero eax 
cld ; Clear direction 

__compute_hash_again: 
lodsb ; Load the next byte from esi into al 
test al, al ; Test ourselves. 
jz __compute_hash_finished ; If the ZF is set, we've hit the null term. 
ror edi, 0xd ; Rotate edi 13 bits to the right 
add edi, eax ; Add the new byte to the accumulator 
jmp __compute_hash_again ; Next iteration 

__compute_hash_finished: 
cmp edi, [esp + 0x28] ; Compare the computed hash with the requested hash 
jnz __find_function_loop ; No match, try the next one. 
mov ebx, [edx + 0x24] ; Ordinals table relative offset 
add ebx, ebp ; Ordinals table VMA 
mov cx, [ebx + 2 * ecx] ; Extrapolate the function's ordinal 
mov ebx, [edx + 0x1c] ; Address table relative offset 
add ebx, ebp ; Address table VMA 
mov eax, [ebx + 4 * ecx] ; Extract the relative function offset from its ordinal 
add eax, ebp ; Function VMA 
mov [esp + 0x1c], eax ; Overwrite stack version of eax from pushad 

__find_function_finished: 
popad ; Restore all registers 
ret 8 

__begin: 
nop 
pop edi ; Pop address 
mov ebx, __execute 
sub ebx, __command_line 
sub edi, ebx ; filename offset 
mov esi,edi ; filename to edi 
call __find_kernel32 ; Find kernel32 address 
mov ebx, eax ; Save address in ebx 
jmp short __execute ; Skip data 

__startup: 
call __begin ; Fetch our data address 


__execute: 
push 0x0e8afe98 ; WinExec hash 
push ebx ; kernel32 base address 
call __find_function ; find address 

xor ecx,ecx 
inc ecx ; ecx = 1 
push ecx ; uCmdShow 
push esi ; lpCmdLine. We already have the exe path in esi 
call eax ; call WinExec 
jmp __end 

__command_line: ; Space (~300 bytes) for commandline 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
nop 
__end: 
pop edi ; restore registers 
pop esi 
pop ebx 
pop ebp 
ret 0x0c 
} 
} 

//************************************************************************ 
// void UtilUserApcCreateProcessEnd() 
// 
// This is just a reference to calculate size of the above usermode apc routine 
//************************************************************************/ 
void UtilUserApcCreateProcessEnd() 
{ 

} 

=================
2222222222=

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -