系统调用(一): 重写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\n",PID);
    printf("X = %x\n",X);
    printf("Xaddr = %x\n",&X);

    getchar();
    printf("X = %x\n",X);
    getchar();
    return 0;
}

 

有两点要注意

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

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

 

posted @ 2021-01-04 21:56  Harmonica11  阅读(519)  评论(0编辑  收藏  举报