zoukankan      html  css  js  c++  java
  • 系统调用(一): 重写WriteProcessMemory

    BOOL WriteProcessMemory(
      HANDLE  hProcess,
      LPVOID  lpBaseAddress,
      LPCVOID lpBuffer,
      SIZE_T  nSize,
      SIZE_T  *lpNumberOfBytesWritten
    );

    首先分析一下kernel32中的WriteProcessMemory,这里不管检查部分

    push    eax             ; NumberOfBytesWritten
    push    ebx             ; NumberOfBytesToWrite
    push    [ebp+Buffer]    ; Buffer
    push    [ebp+lpBaseAddress] ; BaseAddress
    push    edi             ; ProcessHandle
    call    ds:NtWriteVirtualMemory

    分析ntdll中的NtWriteVirtualMemory

    ZwWriteVirtualMemory proc near
    mov     eax, 115h       ; NtWriteVirtualMemory
    mov     edx, 7FFE0300h
    call    dword ptr [edx]
    retn    14h

    这里用到了_KUSER_SHARED_DATA结构

    kd> dt _KUSER_SHARED_DATA
    nt!_KUSER_SHARED_DATA
       +0x000 TickCountLow     : Uint4B
       +0x004 TickCountMultiplier : Uint4B
       +0x008 InterruptTime    : _KSYSTEM_TIME
       +0x014 SystemTime       : _KSYSTEM_TIME
       +0x020 TimeZoneBias     : _KSYSTEM_TIME
       +0x02c ImageNumberLow   : Uint2B
       +0x02e ImageNumberHigh  : Uint2B
       +0x030 NtSystemRoot     : [260] Uint2B
       +0x238 MaxStackTraceDepth : Uint4B
       +0x23c CryptoExponent   : Uint4B
       +0x240 TimeZoneId       : Uint4B
       +0x244 Reserved2        : [8] Uint4B
       +0x264 NtProductType    : _NT_PRODUCT_TYPE
       +0x268 ProductTypeIsValid : UChar
       +0x26c NtMajorVersion   : Uint4B
       +0x270 NtMinorVersion   : Uint4B
       +0x274 ProcessorFeatures : [64] UChar
       +0x2b4 Reserved1        : Uint4B
       +0x2b8 Reserved3        : Uint4B
       +0x2bc TimeSlip         : Uint4B
       +0x2c0 AlternativeArchitecture : _ALTERNATIVE_ARCHITECTURE_TYPE
       +0x2c8 SystemExpirationDate : _LARGE_INTEGER
       +0x2d0 SuiteMask        : Uint4B
       +0x2d4 KdDebuggerEnabled : UChar
       +0x2d5 NXSupportPolicy  : UChar
       +0x2d8 ActiveConsoleId  : Uint4B
       +0x2dc DismountCount    : Uint4B
       +0x2e0 ComPlusPackage   : Uint4B
       +0x2e4 LastSystemRITEventTickCount : Uint4B
       +0x2e8 NumberOfPhysicalPages : Uint4B
       +0x2ec SafeBootMode     : UChar
       +0x2f0 TraceLogging     : Uint4B
       +0x2f8 TestRetInstruction : Uint8B
       +0x300 SystemCall       : Uint4B
       +0x304 SystemCallReturn : Uint4B
       +0x308 SystemCallPad    : [3] Uint8B
       +0x320 TickCount        : _KSYSTEM_TIME
       +0x320 TickCountQuad    : Uint8B
       +0x330 Cookie           : Uint4B

    +300处为系统调用,有两种方式

    KiFastSystemCall
    KiIntSystemCall
    KiIntSystemCall proc near
    arg_4= byte ptr  8
    lea     edx, [esp+arg_4]
    int     2Eh             
    retn
    KiFastSystemCall proc near
    mov     edx, esp
    sysenter

    到这栈为

    分析结束,重写WriteProcessMemory的三环部分

    #include "stdafx.h"
    #include <windows.h>
    
    void __declspec(naked) MyIntWriteProcessMemory(HANDLE  hProcess,
      LPVOID  lpBaseAddress,
      LPCVOID lpBuffer,
      SIZE_T  nSize,
      SIZE_T  *lpNumberOfBytesWritten){
        __asm{
            mov eax,0x115
            lea edx,[esp+4]
            int 0x2e
            ret
        }
    }
    
    void __declspec(naked) MyFastWriteProcessMemory(HANDLE  hProcess,
      LPVOID  lpBaseAddress,
      LPCVOID lpBuffer,
      SIZE_T  nSize,
      SIZE_T  *lpNumberOfBytesWritten){
        __asm{
            push retaddr
            mov eax,0x115
            mov edx,esp
            _emit 0x0f
            _emit 0x34
    retaddr:
            ret
        }
    }
    
    int main(int argc, char* argv[])
    {
    
        DWORD X=0xabcd;
        DWORD addr=0;
        DWORD dwProcessId = 0;
        DWORD check=0;
        printf("input Pid:");
        scanf("%x",&dwProcessId);
        printf("input addr:");
        scanf("%x",&addr);
        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessId);
        //MyIntWriteProcessMemory(hProcess,(char*)addr,(char*)&X,(SIZE_T)4,(SIZE_T*)NULL);
        MyFastWriteProcessMemory(hProcess,(char*)addr,(char*)&X,(SIZE_T)4,(SIZE_T*)NULL);
        return 0;
    }

    测试代码

    #include "stdafx.h"
    #include <windows.h>
    
    int main(int argc, char* argv[])
    {
        DWORD X=0x1234;
        DWORD PID=GetCurrentProcessId();
        printf("PID = %x
    ",PID);
        printf("X = %x
    ",X);
        printf("Xaddr = %x
    ",&X);
    
        getchar();
        printf("X = %x
    ",X);
        getchar();
        return 0;
    }

     

    有两点要注意

    1,在fast时要注意栈的结构

    2,vc6脑瘫编译器把push retaddr编译成了push [retaddr]

  • 相关阅读:
    软件工程第九周总结
    作为使用者对qq拼音输入法和搜狗输入法的评价
    关于编写Windows程序中启动兼容性问题
    软件工程第八周总结
    Java实验--关于课上找“水王”问题分析
    大道至简阅读笔记03
    家庭记账本-----一
    《人月神话》读后感----一到三章
    Java实现数据库与eclipse的连接
    流和文件
  • 原文地址:https://www.cnblogs.com/harmonica11/p/14193594.html
Copyright © 2011-2022 走看看