📄 attach.c
字号:
/* * attach.c * * Copyright (C) 2006 Insigme Co., Ltd * * Authors: * - Liwei Zhou * * This software has been developed while working on the Linux Unified Kernel * project (http://linux.insigma.com.cn) in the Insigma Reaserch Institute, * which is a subdivision of Insigma Co., Ltd (http://www.insigma.com.cn). * * The project is sponsored by Insigma Co., Ltd. * * The authors can be reached at linux@insigma.com.cn. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * Revision History: * Jan 2006 - Created. */ /* * attach.c: attach to another process * Reference to ReactOS code */#include "attach.h"#include "../process.h"#include "../thread.h"#include <linux/winternl.h>#include <asm/pgtable.h>#ifdef CONFIG_UNIFIED_KERNELVOID Ke386SetPageTableDirectory(long X){ __asm__ __volatile__( "movl %0, %%cr3\n\t" : :"r"(X));}/* * MmUpdatePageDir */VOIDSTDCALLMmUpdatePageDir(struct mm_struct *mm, PVOID Address, ULONG Size){ ULONG offset, start_offset, end_offset; struct mm_struct *current_mm = current->mm; ktrace("MmUpdatePageDir\n"); if (Address < (PVOID)TASK_SIZE) { kdebug("invalid address\n"); return; } spin_lock(&mm->page_table_lock); start_offset = pgd_index((ULONG)Address); end_offset = pgd_index((ULONG)Address+ Size); for (offset = start_offset; offset <= end_offset; offset++) { pgd_t *pgd = (pgd_t *)(mm->pgd + offset); if (!pgd->pgd) pgd->pgd = ((pgd_t *)(current_mm->pgd + offset))->pgd; } spin_unlock(&mm->page_table_lock);}/* end MmUpdatePageDir */static inline voidUpdatePageDirs(PKTHREAD Thread, struct mm_struct *mm){ /* * The stack and the thread structure of the current process may be * located in a page which is not present in the page directory of * the process we're attaching to. That would lead to a page fault * when this function returns. However, since the processor can't * call the page fault handler 'cause it can't push EIP on the stack, * this will show up as a stack fault which will crash the entire system. * To prevent this, make sure the page directory of the process we're * attaching to is up-to-date. */ MmUpdatePageDir(mm, (PVOID)Thread->stack_limit, MM_STACK_SIZE); MmUpdatePageDir(mm, (PVOID)Thread, sizeof(struct ethread));}static inlineVOID RepairList(struct list_head *Original, struct list_head *Copy, KPROCESSOR_MODE Mode){ /* Copy Source to Desination */ if (list_empty(&Original[(int)Mode])) INIT_LIST_HEAD(&Copy[(int)Mode]); else { Copy[(int)Mode].next = Original[(int)Mode].next; Copy[(int)Mode].prev = Original[(int)Mode].prev; Original[(int)Mode].next->prev = &Copy[(int)Mode]; Original[(int)Mode].prev->next = &Copy[(int)Mode]; }}/* * KiMoveApcState */VOIDSTDCALLKiMoveApcState(struct kapc_state *OldState, struct kapc_state *NewState){ /* Restore backup of Original Environment */ *NewState = *OldState; /* Repair Lists */ RepairList(NewState->apc_list_head, OldState->apc_list_head, KernelMode); RepairList(NewState->apc_list_head, OldState->apc_list_head, UserMode);} /* end KiMoveApcState *//* * KiAttackProcess */VOIDSTDCALLKiAttachProcess(struct kthread *Thread, struct kprocess *Process, UCHAR ApcLock, struct kapc_state *SavedApcState){ /* Increase Stack Count */ Process->stack_count++; /* Swap the APC Environment */ KiMoveApcState(&Thread->apc_state, SavedApcState); /* Reinitialize Apc State */ INIT_LIST_HEAD(&Thread->apc_state.apc_list_head[KernelMode]); INIT_LIST_HEAD(&Thread->apc_state.apc_list_head[UserMode]); Thread->apc_state.process = Process; Thread->apc_state.kapc_inprogress = FALSE; Thread->apc_state.kapc_pending = FALSE; Thread->apc_state.uapc_pending = FALSE; /* Update Environment Pointers if needed*/ if (SavedApcState == &Thread->saved_apc_state) { Thread->apc_state_pointer[OriginalApcEnvironment] = &Thread->saved_apc_state; Thread->apc_state_pointer[AttachedApcEnvironment] = &Thread->apc_state; Thread->apc_state_index = AttachedApcEnvironment; }} /* end KiAttachProcess *//* * KeAttachProcess */struct mm_struct *KeAttachProcess(struct kprocess *Process){ struct ethread *current_thread = thread_find(); struct ethread *thread; struct mm_struct *mm, *old_mm; ktrace("KeAttachProcess\n"); thread = get_first_thread((struct eprocess *)Process); mm = thread->et_task->mm; /* Make sure that we are in the right page directory */ UpdatePageDirs(¤t_thread->tcb, mm); local_irq_disable(); KiAttachProcess(¤t_thread->tcb, Process, 0, ¤t_thread->tcb.saved_apc_state); /* Swap the Processes */ Ke386SetPageTableDirectory(__pa(mm->pgd)); old_mm = current->mm; current->mm = mm; local_irq_enable(); return old_mm;} /* end KeAttachProcess *//* * KeDetachProcess */VOIDSTDCALLKeDetachProcess (struct mm_struct *mm){ struct ethread *thread = thread_find(); ktrace("KeDetachProcess\n"); local_irq_disable(); /* Decrease Stack Count */ thread->threads_process->pcb.stack_count--; /* Restrore the APC State */ KiMoveApcState(&thread->tcb.saved_apc_state, &thread->tcb.apc_state); thread->tcb.saved_apc_state.process = NULL; thread->tcb.apc_state_pointer[OriginalApcEnvironment] = &thread->tcb.apc_state; thread->tcb.apc_state_pointer[AttachedApcEnvironment] = &thread->tcb.saved_apc_state; thread->tcb.apc_state_index = OriginalApcEnvironment; /* Swap Processes */ Ke386SetPageTableDirectory(__pa(mm->pgd)); current->mm = mm; local_irq_enable();} /* end KeDetachProcess */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -