首页
社区
课程
招聘
[分享]立此存照(来源于WRK-1.2)
发表于: 2007-11-22 19:35 10829

[分享]立此存照(来源于WRK-1.2)

2007-11-22 19:35
10829
page ,132
        subttl "Debug Exception"
;++
;
; Routine Description:
;
;    Handle debug exception.
;
;    The processor triggers this exception for any of the following
;    conditions:
;
;    1. Instruction breakpoint fault.
;    2. Data address breakpoint trap.
;    3. General detect fault.
;    4. Single-step trap.
;    5. Task-switch breakpoint trap.
;
;
; Arguments:
;
;    At entry, the values of saved CS and EIP depend on whether the
;    exception is a fault or a trap.
;    No error code is provided with the divide error.
;
; Return value:
;
;    None
;
;--
        ASSUME  DS:NOTHING, SS:NOTHING, ES:NOTHING
align dword
;
; We branch here to handle a trap01 fromt he fast system call entry
; we need to propagate the trap bit to the return eflags etc and
; continue.
;

Kt0100: mov     [ebp].TsEip, _KiFastCallEntry2
        and     dword ptr [ebp].TsEflags, NOT EFLAGS_TF
        jmp     _KiExceptionExit        ; join common code

        ENTER_DR_ASSIST kit1_a, kit1_t, NoAbiosAssist
align dword
        public  _KiTrap01
_KiTrap01       proc

; Set up machine state frame for displaying

        push    0                       ; push dummy error code
        ENTER_TRAP      kit1_a, kit1_t

;
; Inspect old EIP in case this is a single stepped
; sysenter instruction.
;

        mov     ecx, [ebp]+TsEip
        cmp     ecx, _KiFastCallEntry
        je      Kt0100

;
; See if were doing the fast bop optimization of touching user memory
; with ints disabled. If we are then ignore data breakpoints.
;
;
if FAST_BOP

        cmp     dword ptr PCR[PcVdmAlert], 0

        jne     Kt01VdmAlert

endif

;
; If caller is user mode, we want interrupts back on.
;   . all relevant state has already been saved
;   . user mode code always runs with ints on
;
; If caller is kernel mode, we want them off!
;   . some state still in registers, must prevent races
;   . kernel mode code can run with ints off
;
;

.errnz (EFLAGS_V86_MASK AND 0FF00FFFFh)
        test    byte ptr [ebp]+TsEFlags+2,EFLAGS_V86_MASK/010000h
        jnz     kit01_30                ; fault occured in V86 mode => Usermode

.errnz (MODE_MASK AND 0FFFFFF00h)
        test    byte ptr [ebp]+TsSegCs,MODE_MASK
        jz      kit01_10

        cmp     word ptr [ebp]+TsSegCs,KGDT_R3_CODE OR RPL_MASK
        jne     kit01_30
kit01_05:
        sti
kit01_10:

;
; Set up exception record for raising single step exception
; and call _KiDispatchException
;

kit01_20:
        and     dword ptr [ebp]+TsEflags, not EFLAGS_TF
        mov     ebx, [ebp]+TsEip                ; (ebx)-> faulting instruction
        mov     eax, STATUS_SINGLE_STEP
        jmp     CommonDispatchException0Args    ; Never return

kit01_30:

; Check to see if this process is a vdm

        mov     ebx,PCR[PcPrcbData+PbCurrentThread]
        mov     ebx,[ebx]+ThApcState+AsProcess
        cmp     dword ptr [ebx]+PrVdmObjects,0 ; is this a vdm process?
        je      kit01_05

        stdCall _Ki386VdmReflectException_A, <01h>
        test    ax,0FFFFh
        jz      Kit01_20
        jmp     _KiExceptionExit

if FAST_BOP

Kt01VdmAlert:

        ;
        ; If a DEBUG trap occured while we are in VDM alert mode (processing
        ; v86 trap without building trap frame), we will restore all the
        ; registers and return to its recovery routine.
        ;

        mov     eax, PCR[PcVdmAlert]
        mov     dword ptr PCR[PcVdmAlert], 0

        mov     [ebp].TsEip, eax
        mov     esp,ebp                 ; (esp) -> trap frame
        jmp     _KiExceptionExit        ; join common code

endif   ; FAST_BOP

_KiTrap01       endp

-------------------------------------------------------------------------------------------

        page ,132
        subttl "Single Byte INT3 Breakpoint"
;++
;
; Routine Description:
;
;    Handle INT 3 breakpoint.
;
;    The trap is caused by a single byte INT 3 instruction.  A
;    BREAKPOINT exception with additional parameter indicating
;    READ access is raised for this trap if previous mode is user.
;
; Arguments:
;
;    At entry, the saved CS:EIP point to the instruction immediately
;    following the INT 3 instruction.
;    No error code is provided with the error.
;
; Return value:
;
;    None
;
;--
        ASSUME  DS:NOTHING, SS:NOTHING, ES:NOTHING

        ENTER_DR_ASSIST kit3_a, kit3_t, NoAbiosAssist
align dword
        public  _KiTrap03
_KiTrap03       proc
        push    0                       ; push dummy error code
        ENTER_TRAP      kit3_a, kit3_t

        cmp     ds:_PoHiberInProgress, 0
        jnz     short kit03_01

   lock inc     ds:_KiHardwareTrigger   ; trip hardware analyzer

kit03_01:
        mov     eax, BREAKPOINT_BREAK

KiTrap03DebugService:
;
; If caller is user mode, we want interrupts back on.
;   . all relevant state has already been saved
;   . user mode code always runs with ints on
;
; If caller is kernel mode, we want them off!
;   . some state still in registers, must prevent races
;   . kernel mode code can run with ints off
;
;
; Arguments:
;     eax - ServiceClass - which call is to be performed
;     ecx - Arg1 - generic first argument
;     edx - Arg2 - generic second argument
;

.errnz (EFLAGS_V86_MASK AND 0FF00FFFFh)
        test    byte ptr [ebp]+TsEFlags+2,EFLAGS_V86_MASK/010000h
        jnz     kit03_30                ; fault occured in V86 mode => Usermode

.errnz (MODE_MASK AND 0FFFFFF00h)
        test    byte ptr [ebp]+TsSegCs,MODE_MASK
        jz      kit03_10

        cmp     word ptr [ebp]+TsSegCs,KGDT_R3_CODE OR RPL_MASK
        jne     kit03_30

kit03_05:
        sti
kit03_10:

;
; Set up exception record and arguments for raising breakpoint exception
;

        mov     esi, ecx                ; ExceptionInfo 2
        mov     edi, edx                ; ExceptionInfo 3
        mov     edx, eax                ; ExceptionInfo 1

        mov     ebx, [ebp]+TsEip
        dec     ebx                     ; (ebx)-> int3 instruction
        mov     ecx, 3
        mov     eax, STATUS_BREAKPOINT
        call    CommonDispatchException ; Never return

kit03_30:
; Check to see if this process is a vdm

        mov     ebx,PCR[PcPrcbData+PbCurrentThread]
        mov     ebx,[ebx]+ThApcState+AsProcess
        cmp     dword ptr [ebx]+PrVdmObjects,0 ; is this a vdm process?
        je      kit03_05

        stdCall _Ki386VdmReflectException_A, <03h>
        test    ax,0FFFFh
        jz      Kit03_10

        jmp     _KiExceptionExit

_KiTrap03       endp

-----------------------------------------------------------------------------------------

        page , 132
        subttl "dispatch exception"

;++
;
; CommonDispatchException
;
; Routine Description:
;
;    This routine allocates exception record on stack, sets up exception
;    record using specified parameters and finally sets up arguments
;    and calls _KiDispatchException.
;
;    NOTE:
;
;    The purpose of this routine is to save code space.  Use this routine
;    only if:
;    1. ExceptionRecord is NULL
;    2. ExceptionFlags is 0
;    3. Number of parameters is less or equal than 3.
;
;    Otherwise, you should use DISPATCH_EXCEPTION macro to set up your special
;    exception record.
;
; Arguments:
;
;    (eax) = ExcepCode - Exception code to put into exception record
;    (ebx) = ExceptAddress - Addr of instruction which the hardware exception occurs
;    (ecx) = NumParms - Number of additional parameters
;    (edx) = Parameter1
;    (esi) = Parameter2
;    (edi) = Parameter3
;
; Return Value:
;
;    None.
;
;--
CommonDispatchException0Args:
        xor     ecx, ecx                ; zero arguments
        call    CommonDispatchException

CommonDispatchException1Arg0d:
        xor     edx, edx                ; zero edx
CommonDispatchException1Arg:
        mov     ecx, 1                  ; one argument
        call    CommonDispatchException ; there is no return

CommonDispatchException2Args0d:
        xor     edx, edx                ; zero edx
CommonDispatchException2Args:
        mov     ecx, 2                  ; two arguments
        call    CommonDispatchException ; there is no return

      public CommonDispatchException
align dword
CommonDispatchException proc
cPublicFpo 0, ExceptionRecordLength/4
;
;       Set up exception record for raising exception
;

        sub     esp, ExceptionRecordLength
                                        ; allocate exception record
        mov     dword ptr [esp]+ErExceptionCode, eax
                                        ; set up exception code
        xor     eax, eax
        mov     dword ptr [esp]+ErExceptionFlags, eax
                                        ; set exception flags
        mov     dword ptr [esp]+ErExceptionRecord, eax
                                        ; set associated exception record
        mov     dword ptr [esp]+ErExceptionAddress, ebx
        mov     dword ptr [esp]+ErNumberParameters, ecx
                                        ; set number of parameters
        cmp     ecx, 0
        je      short de00

        lea     ebx, [esp + ErExceptionInformation]
        mov     [ebx], edx
        mov     [ebx+4], esi
        mov     [ebx+8], edi
de00:
;
; set up arguments and call _KiDispatchException
;

        mov     ecx, esp                ; (ecx)->exception record

.errnz (EFLAGS_V86_MASK AND 0FF00FFFFh)
        test    byte ptr [ebp]+TsEFlags+2,EFLAGS_V86_MASK/010000h
        jz      short de10

        mov     eax,0FFFFh
        jmp     short de20

de10:   mov     eax,[ebp]+TsSegCs
de20:   and     eax,MODE_MASK

; 1 - first chance TRUE
; eax - PreviousMode
; ebp - trap frame addr
; 0 - Null exception frame
; ecx - exception record addr

        stdCall _KiDispatchException,<ecx, 0, ebp, eax, 1>

        mov     esp, ebp                ; (esp) -> trap frame
        jmp     _KiExceptionExit

CommonDispatchException endp

--------------------------------------------------------------------------------------------

VOID
KiDispatchException (
    IN PEXCEPTION_RECORD ExceptionRecord,
    IN PKEXCEPTION_FRAME ExceptionFrame,
    IN PKTRAP_FRAME TrapFrame,
    IN KPROCESSOR_MODE PreviousMode,
    IN BOOLEAN FirstChance
    )

/*++

Routine Description:

    This function is called to dispatch an exception to the proper mode and
    to cause the exception dispatcher to be called. If the previous mode is
    kernel, then the exception dispatcher is called directly to process the
    exception. Otherwise the exception record, exception frame, and trap
    frame contents are copied to the user mode stack. The contents of the
    exception frame and trap are then modified such that when control is
    returned, execution will commense in user mode in a routine which will
    call the exception dispatcher.

Arguments:

    ExceptionRecord - Supplies a pointer to an exception record.

    ExceptionFrame - Supplies a pointer to an exception frame. For NT386,
        this should be NULL.

    TrapFrame - Supplies a pointer to a trap frame.

    PreviousMode - Supplies the previous processor mode.

    FirstChance - Supplies a boolean value that specifies whether this is
        the first (TRUE) or second (FALSE) chance for the exception.

Return Value:

    None.

--*/

{
    CONTEXT ContextFrame;
    EXCEPTION_RECORD ExceptionRecord1, ExceptionRecord2;
    LONG Length;
    ULONG UserStack1;
    ULONG UserStack2;

    //
    // Move machine state from trap and exception frames to a context frame,
    // and increment the number of exceptions dispatched.
    //

    KeGetCurrentPrcb()->KeExceptionDispatchCount += 1;
    ContextFrame.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;

    if ((PreviousMode == UserMode) || KdDebuggerEnabled) {
        //
        // For usermode exceptions always try to dispatch the floating
        // point state.  This allows exception handlers & debuggers to
        // examine/edit the npx context if required.  Plus it allows
        // exception handlers to use fp instructions without destroying
        // the npx state at the time of the exception.
        //
        // Note: If there's no 80387, ContextTo/FromKFrames will use the
        // emulator's current state.  If the emulator can not give the
        // current state, then the context_floating_point bit will be
        // turned off by ContextFromKFrames.
        //

        ContextFrame.ContextFlags |= CONTEXT_FLOATING_POINT;
        if (KeI386XMMIPresent) {
            ContextFrame.ContextFlags |= CONTEXT_EXTENDED_REGISTERS;
        }
    }

    KeContextFromKframes(TrapFrame, ExceptionFrame, &ContextFrame);

    //
    // if it is BREAK_POINT exception, we subtract 1 from EIP and report
    // the updated EIP to user.  This is because Cruiser requires EIP
    // points to the int 3 instruction (not the instruction following int 3).
    // In this case, BreakPoint exception is fatal. Otherwise we will step
    // on the int 3 over and over again, if user does not handle it
    //
    // if the BREAK_POINT occured in V86 mode, the debugger running in the
    // VDM will expect CS:EIP to point after the exception (the way the
    // processor left it.  this is also true for protected mode dos
    // app debuggers.  We will need a way to detect this.
    //
    //

    switch (ExceptionRecord->ExceptionCode) {
        case STATUS_BREAKPOINT:
            ContextFrame.Eip--;
            break;

        case KI_EXCEPTION_ACCESS_VIOLATION:
            ExceptionRecord->ExceptionCode = STATUS_ACCESS_VIOLATION;
            if (PreviousMode == UserMode) {
                if (KiCheckForAtlThunk(ExceptionRecord,&ContextFrame) != FALSE) {
                    goto Handled1;
                }

                if ((SharedUserData->ProcessorFeatures[PF_NX_ENABLED] == TRUE) &&
                    (ExceptionRecord->ExceptionInformation [0] == EXCEPTION_EXECUTE_FAULT)) {
                    
                    if (((KeFeatureBits & KF_GLOBAL_32BIT_EXECUTE) != 0) ||
                        (PsGetCurrentProcess()->Pcb.Flags.ExecuteEnable != 0) ||
                        (((KeFeatureBits & KF_GLOBAL_32BIT_NOEXECUTE) == 0) &&
                         (PsGetCurrentProcess()->Pcb.Flags.ExecuteDisable == 0))) {
                        ExceptionRecord->ExceptionInformation [0] = 0;
                    }
                }
            }
            break;
    }

    //
    // Select the method of handling the exception based on the previous mode.
    //

    ASSERT ((
             !((PreviousMode == KernelMode) &&
             (ContextFrame.EFlags & EFLAGS_V86_MASK))
           ));

    if (PreviousMode == KernelMode) {

        //
        // Previous mode was kernel.
        //
        // If the kernel debugger is active, then give the kernel debugger the
        // first chance to handle the exception. If the kernel debugger handles
        // the exception, then continue execution. Else attempt to dispatch the
        // exception to a frame based handler. If a frame based handler handles
        // the exception, then continue execution.
        //
        // If a frame based handler does not handle the exception,
        // give the kernel debugger a second chance, if it's present.
        //
        // If the exception is still unhandled, call KeBugCheck().
        //

        if (FirstChance == TRUE) {

            if ((KiDebugRoutine != NULL) &&
               (((KiDebugRoutine) (TrapFrame,
                                   ExceptionFrame,
                                   ExceptionRecord,
                                   &ContextFrame,
                                   PreviousMode,
                                   FALSE)) != FALSE)) {

                goto Handled1;
            }

            // Kernel debugger didn't handle exception.

            if (RtlDispatchException(ExceptionRecord, &ContextFrame) == TRUE) {
                goto Handled1;
            }
        }

        //
        // This is the second chance to handle the exception.
        //

        if ((KiDebugRoutine != NULL) &&
            (((KiDebugRoutine) (TrapFrame,
                                ExceptionFrame,
                                ExceptionRecord,
                                &ContextFrame,
                                PreviousMode,
                                TRUE)) != FALSE)) {

            goto Handled1;
        }

        KeBugCheckEx(
            KERNEL_MODE_EXCEPTION_NOT_HANDLED,
            ExceptionRecord->ExceptionCode,
            (ULONG)ExceptionRecord->ExceptionAddress,
            (ULONG)TrapFrame,
            0);

    } else {

        //
        // Previous mode was user.
        //
        // If this is the first chance and the current process has a debugger
        // port, then send a message to the debugger port and wait for a reply.
        // If the debugger handles the exception, then continue execution. Else
        // transfer the exception information to the user stack, transition to
        // user mode, and attempt to dispatch the exception to a frame based
        // handler. If a frame based handler handles the exception, then continue
        // execution with the continue system service. Else execute the
        // NtRaiseException system service with FirstChance == FALSE, which
        // will call this routine a second time to process the exception.
        //
        // If this is the second chance and the current process has a debugger
        // port, then send a message to the debugger port and wait for a reply.
        // If the debugger handles the exception, then continue execution. Else
        // if the current process has a subsystem port, then send a message to
        // the subsystem port and wait for a reply. If the subsystem handles the
        // exception, then continue execution. Else terminate the process.
        //

        if (FirstChance == TRUE) {

            //
            // This is the first chance to handle the exception.
            //

            if ((KiDebugRoutine != NULL)  &&
                ((PsGetCurrentProcess()->DebugPort == NULL &&
                  !KdIgnoreUmExceptions) ||
                 (KdIsThisAKdTrap(ExceptionRecord, &ContextFrame, UserMode)))) {
                //
                // Now dispatch the fault to the kernel debugger.
                //

                if ((((KiDebugRoutine) (TrapFrame,
                                        ExceptionFrame,
                                        ExceptionRecord,
                                        &ContextFrame,
                                        PreviousMode,
                                        FALSE)) != FALSE)) {

                    goto Handled1;
                }
            }

            if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) {
                goto Handled2;
            }

            //
            // Transfer exception information to the user stack, transition
            // to user mode, and attempt to dispatch the exception to a frame
            // based handler.

            ExceptionRecord1.ExceptionCode = 0; // satisfy no_opt compilation

        repeat:
            try {

                //
                // If the SS segment is not 32 bit flat, there is no point
                // to dispatch exception to frame based exception handler.
                //

                if (TrapFrame->HardwareSegSs != (KGDT_R3_DATA | RPL_MASK) ||
                    TrapFrame->EFlags & EFLAGS_V86_MASK ) {
                    ExceptionRecord2.ExceptionCode = STATUS_ACCESS_VIOLATION;
                    ExceptionRecord2.ExceptionFlags = 0;
                    ExceptionRecord2.NumberParameters = 0;
                    ExRaiseException(&ExceptionRecord2);
                }

                //
                // Compute length of context record and new aligned user stack
                // pointer.
                //

                UserStack1 = (ContextFrame.Esp & ~CONTEXT_ROUND) - CONTEXT_ALIGNED_SIZE;

                //
                // Probe user stack area for writability and then transfer the
                // context record to the user stack.
                //

                ProbeForWrite((PCHAR)UserStack1, CONTEXT_ALIGNED_SIZE, CONTEXT_ALIGN);
                RtlCopyMemory((PULONG)UserStack1, &ContextFrame, sizeof(CONTEXT));

                //
                // Compute length of exception record and new aligned stack
                // address.
                //

                Length = (sizeof(EXCEPTION_RECORD) - (EXCEPTION_MAXIMUM_PARAMETERS -
                         ExceptionRecord->NumberParameters) * sizeof(ULONG) +3) &
                         (~3);
                UserStack2 = UserStack1 - Length;

                //
                // Probe user stack area for writeability and then transfer the
                // context record to the user stack area.
                // N.B. The probing length is Length+8 because there are two
                //      arguments need to be pushed to user stack later.
                //

                ProbeForWrite((PCHAR)(UserStack2 - 8), Length + 8, sizeof(ULONG));
                RtlCopyMemory((PULONG)UserStack2, ExceptionRecord, Length);

                //
                // Push address of exception record, context record to the
                // user stack.  They are the two parameters required by
                // _KiUserExceptionDispatch.
                //

                *(PULONG)(UserStack2 - sizeof(ULONG)) = UserStack1;
                *(PULONG)(UserStack2 - 2*sizeof(ULONG)) = UserStack2;

                //
                // Set new stack pointer to the trap frame.
                //

                KiSegSsToTrapFrame(TrapFrame, KGDT_R3_DATA);
                KiEspToTrapFrame(TrapFrame, (UserStack2 - sizeof(ULONG)*2));

                //
                // Force correct R3 selectors into TrapFrame.
                //

                TrapFrame->SegCs = SANITIZE_SEG(KGDT_R3_CODE, PreviousMode);
                TrapFrame->SegDs = SANITIZE_SEG(KGDT_R3_DATA, PreviousMode);
                TrapFrame->SegEs = SANITIZE_SEG(KGDT_R3_DATA, PreviousMode);
                TrapFrame->SegFs = SANITIZE_SEG(KGDT_R3_TEB, PreviousMode);
                TrapFrame->SegGs = 0;

                //
                // Set the address of the exception routine that will call the
                // exception dispatcher and then return to the trap handler.
                // The trap handler will restore the exception and trap frame
                // context and continue execution in the routine that will
                // call the exception dispatcher.
                //

                TrapFrame->Eip = (ULONG)KeUserExceptionDispatcher;
                return;

            } except (KiCopyInformation(&ExceptionRecord1,
                        (GetExceptionInformation())->ExceptionRecord)) {

                //
                // If the exception is a stack overflow, then attempt
                // to raise the stack overflow exception. Otherwise,
                // the user's stack is not accessible, or is misaligned,
                // and second chance processing is performed.
                //

                if (ExceptionRecord1.ExceptionCode == STATUS_STACK_OVERFLOW) {
                    ExceptionRecord1.ExceptionAddress = ExceptionRecord->ExceptionAddress;
                    RtlCopyMemory((PVOID)ExceptionRecord,
                                  &ExceptionRecord1, sizeof(EXCEPTION_RECORD));
                    goto repeat;
                }
            }
        }

        //
        // This is the second chance to handle the exception.
        //

        if (DbgkForwardException(ExceptionRecord, TRUE, TRUE)) {
            goto Handled2;
        } else if (DbgkForwardException(ExceptionRecord, FALSE, TRUE)) {
            goto Handled2;
        } else {
            ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode);
            KeBugCheckEx(
                KERNEL_MODE_EXCEPTION_NOT_HANDLED,
                ExceptionRecord->ExceptionCode,
                (ULONG)ExceptionRecord->ExceptionAddress,
                (ULONG)TrapFrame,
                0);
        }
    }

    //
    // Move machine state from context frame to trap and exception frames and
    // then return to continue execution with the restored state.
    //

Handled1:

    KeContextToKframes(TrapFrame, ExceptionFrame, &ContextFrame,
                       ContextFrame.ContextFlags, PreviousMode);

    //
    // Exception was handled by the debugger or the associated subsystem
    // and state was modified, if necessary, using the get state and set
    // state capabilities. Therefore the context frame does not need to
    // be transferred to the trap and exception frames.
    //

Handled2:
    return;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 215
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
究竟是什么作用?antidebug?
2007-11-22 19:47
0
雪    币: 80
活跃值: (14)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
呵呵,难道真的没有人知道我从WRK上摘下来的这代码片段是干什么的吗?这是WINDOWS操作系统上用于处理异常的代码,前三个例程都是汇编。其中前两个分别是当促发指令中断异常或调试异常时首先会执行的代码,这两段代码最终都要建立参数,然后通过第三个汇编例程调用最后一个KiDispatchException例程,这个例程是WINDOWS中异常分发机制的入口。

感觉微软的代码写的真是好,格式工整漂亮的没话说。
2007-11-22 21:49
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
4
汗.fuckrdtsc好像就是hook 的KiDispatchException
2007-11-22 22:11
0
雪    币: 339
活跃值: (1510)
能力值: ( LV13,RANK:970 )
在线值:
发帖
回帖
粉丝
5
貌似hook 的KiDispatchException可以干很多很多事情,屁如可以做个通用找OEP的工具
2007-11-22 22:28
0
雪    币: 8209
活跃值: (4518)
能力值: ( LV15,RANK:2473 )
在线值:
发帖
回帖
粉丝
6
太深奥了,慢慢学习
2007-11-22 23:31
0
雪    币: 226
活跃值: (15)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
我只能说学习
2007-11-22 23:37
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
8
支持楼主把WRK都贴上来,再把W2K也贴上来,再把*NIX都贴上来,顺便也把*BSD贴上来,把所有代码都贴上来,一起学习一下。
2007-11-23 00:46
0
雪    币: 107
活跃值: (11)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
WRK的完整光盘哪个大侠可以贡献一下啊
2007-11-23 02:09
0
雪    币: 116
活跃值: (220)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
10
严重批准~~~
2007-11-23 09:02
0
雪    币: 248
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
啥话都不说,先学习下。。。
2007-11-28 12:56
0
游客
登录 | 注册 方可回帖
返回
//