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