• 系统调用(一): 重写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]

  • 相关阅读:
    超大文件上传-如何上传文件-大文件上传
    局域网 前端大文件上传
    B/S 前端大文件上传
    PHP 前端大文件上传
    .NET 前端大文件上传
    C#.NET 前端大文件上传
    ASP.NET 前端大文件上传
    SpringBoot 前端大文件上传
    SpringMVC 前端大文件上传
    JAVA 前端大文件上传
  • 原文地址:https://www.cnblogs.com/harmonica11/p/14193594.html
Copyright © 2020-2023  润新知