15,471
社区成员
发帖
与我相关
我的任务
分享
MEMORY_BASIC_INFORMATION mbi;
BOOL bOk = (VirtualQueryEx(hProcess, pvAddress, &mbi, sizeof(mbi))
== sizeof(mbi));
int main()
{
DWORD flProtect = PAGE_EXECUTE_READ;//此处不能有 WRITECOPY属性 否则VirtualAlloc 将失败
printf("测试属性 :%x\n",flProtect);
void *myMemory = VirtualAlloc(NULL,1024*4,MEM_RESERVE|MEM_COMMIT,flProtect);
MEMORY_BASIC_INFORMATION mbi;
BOOL bOk = (VirtualQuery(myMemory,&mbi,sizeof(mbi)) == sizeof(mbi));
printf("初始属性 :%x\n",mbi.Protect);
WriteProcessMemory(GetCurrentProcess(),myMemory,"abc",sizeof("abc"),NULL);
bOk = (VirtualQuery(myMemory,&mbi,sizeof(mbi)) == sizeof(mbi));
printf("之后 :%x\n",mbi.Protect);
return 0;
}
.text:7C8022F9 ; ---------------------------------------------------------------------------
.text:7C8022F9
.text:7C8022F9 lblPageNoAccessOrReadOnly: ; CODE XREF: WriteProcessMemory+A8j
.text:7C8022F9 lea ecx, [ebp+nSize] ; 恢复旧的 access等级
.text:7C8022FC push ecx
.text:7C8022FD push eax
.text:7C8022FE lea eax, [ebp+lpPageSize]
.text:7C802301 push eax
.text:7C802302 lea eax, [ebp+lpPageStartAddress]
.text:7C802305 push eax
.text:7C802306 push edi
.text:7C802307 call esi ; NtProtectVirtualMemory
.text:7C802309 xor esi, esi
.text:7C80230B
.text:7C80230B lblThrowAccessViolation: ; CODE XREF: WriteProcessMemory+E8j
.text:7C80230B push 0C0000005h
.text:7C802310 call sub_7C80936B
.text:7C802315 mov eax, esi
.text:7C802317 jmp lblExitNoError ; 清理现场
.text:7C80231C ; ---------------------------------------------------------------------------
.text:7C80231C
.text:7C80231C loc_7C80231C: ; CODE XREF: WriteProcessMemory+69j
.text:7C80231C mov edx, [ebp+hProcess]
.text:7C80231F mov [ecx], edx
.text:7C802321 jmp lblTestIfMMF_OrSharedWriteFailed
.text:7C802326 ; ---------------------------------------------------------------------------
.text:7C802326
.text:7C802326 lblFail: ; CODE XREF: WriteProcessMemory+8Ej
.text:7C802326 xor eax, eax ; 错误!
.text:7C802328 jmp lblExitNoError ; 清理现场
.text:7C802328 WriteProcessMemory endp
.text:7C80220F ; BOOL __stdcall WriteProcessMemory(HANDLE hProcess,LPVOID lpBaseAddress,LPVOID lpBuffer,DWORD nSize,LPDWORD lpNumberOfBytesWritten)
.text:7C80220F public WriteProcessMemory
.text:7C80220F WriteProcessMemory proc near
.text:7C80220F
.text:7C80220F lpPageStartAddress= dword ptr -8
.text:7C80220F lpPageSize = dword ptr -4
.text:7C80220F hProcess = dword ptr 8
.text:7C80220F lpBaseAddress = dword ptr 0Ch
.text:7C80220F lpBuffer = dword ptr 10h
.text:7C80220F nSize = dword ptr 14h
.text:7C80220F lpNumberOfBytesWritten= dword ptr 18h
.text:7C80220F
.text:7C80220F mov edi, edi ;
.text:7C802211 push ebp
.text:7C802212 mov ebp, esp
.text:7C802214 push ecx
.text:7C802215 push ecx
.text:7C802216 mov eax, [ebp+lpBaseAddress]
.text:7C802219 push ebx ;
.text:7C802219 ;
.text:7C80221A mov ebx, [ebp+nSize]
.text:7C80221D push esi ;
.text:7C80221E mov esi, ds:NtProtectVirtualMemory
.text:7C802224 push edi ;
.text:7C802225 mov edi, [ebp+hProcess]
.text:7C802228 mov [ebp+lpPageStartAddress], eax
.text:7C80222B lea eax, [ebp+nSize] ; 这里让nSize偏移处保持旧的access值
.text:7C80222E push eax
.text:7C80222F push 40h ; PAGE_EXECUTE_READWRITE,亮点
.text:7C802231 lea eax, [ebp+lpPageSize]
.text:7C802234 push eax
.text:7C802235 lea eax, [ebp+lpPageStartAddress]
.text:7C802238 push eax
.text:7C802239 push edi
.text:7C80223A mov [ebp+lpPageSize], ebx
.text:7C80223D call esi ; NtProtectVirtualMemory
.text:7C80223F cmp eax, 0C000004Eh ; STATUS_SECTION_PROTECTION
.text:7C80223F ;
.text:7C80223F ; 这里没有执行权限
.text:7C802244 jz short lblDontHaveExecuteRights
.text:7C802246
.text:7C802246 lblTestMemoryAccess: ; CODE XREF: WriteProcessMemory+A4j
.text:7C802246 test eax, eax
.text:7C802248 jl short lblNoteError
.text:7C80224A mov eax, [ebp+nSize]
.text:7C80224D test al, 0CCh ; 这里做位与判断,和我们判断页权限的代码相同,这里做了实现:
.text:7C80224D ;
.text:7C80224D ; PAGE_EXECUTE_READWRITE |
.text:7C80224D ; PAGE_READWRITE |
.text:7C80224D ; PAGE_EXECUTE_WRITECOPY |
.text:7C80224D ; PAGE_WRITECOPY
.text:7C80224D ;
.text:7C80224D ;
.text:7C80224F jz short lblNotMMF_OrShared ; 判断是否和旧 access值相同
.text:7C80224F ;
.text:7C80224F ; PAGE_NOACCESS |
.text:7C80224F ; PAGE_READONLY
.text:7C802251 lea ecx, [ebp+nSize] ; 恢复旧的 access
.text:7C802251 ;
.text:7C802254 push ecx
.text:7C802255 push eax
.text:7C802256 lea eax, [ebp+lpPageSize]
.text:7C802259 push eax
.text:7C80225A lea eax, [ebp+lpPageStartAddress]
.text:7C80225D push eax
.text:7C80225E push edi
.text:7C80225F call esi ; NtProtectVirtualMemory 亮点哦
.text:7C802261 lea eax, [ebp+hProcess]
.text:7C802264 push eax
.text:7C802265 push ebx
.text:7C802266 push [ebp+lpBuffer]
.text:7C802269 push [ebp+lpBaseAddress]
.text:7C80226C push edi
.text:7C80226D call ds:NtWriteVirtualMemory ;再写
.text:7C802273 mov ecx, [ebp+lpNumberOfBytesWritten]
.text:7C802276 test ecx, ecx
.text:7C802278 jnz loc_7C80231C
.text:7C80227E
.text:7C80227E lblTestIfMMF_OrSharedWriteFailed: ; CODE XREF: WriteProcessMemory+112j
.text:7C80227E test eax, eax
.text:7C802280 jl short lblNoteError
.text:7C802282
.text:7C802282 lblFlushInstructions: ; CODE XREF: WriteProcessMemory+E1j
.text:7C802282 push ebx
.text:7C802283 push [ebp+lpBaseAddress]
.text:7C802286 push edi
.text:7C802287 call ds:NtFlushInstructionCache 这个地方熟悉吧?刷缓存
.text:7C80228D xor eax, eax
.text:7C80228F inc eax
.text:7C802290
.text:7C802290 lblExitNoError: ; CODE XREF: WriteProcessMemory+108j
.text:7C802290 ; WriteProcessMemory+119j
.text:7C802290 pop edi ;
.text:7C802291 pop esi
.text:7C802292 pop ebx
.text:7C802293 leave
.text:7C802294 retn 14h
.text:7C802297 ; ---------------------------------------------------------------------------
.text:7C802297
.text:7C802297 lblNoteError: ; CODE XREF: WriteProcessMemory+39j
.text:7C802297 ; WriteProcessMemory+71j
.text:7C802297 push eax
.text:7C802298 call sub_7C80936B ; 这个函数把错误码转换为系统错误并将其放在TEB里面
.text:7C802298 ;
.text:7C802298 ;
.text:7C80229D jmp lblFail ; 错误了
.text:7C8022A2 ; ---------------------------------------------------------------------------
.text:7C8022A2
.text:7C8022A2 lblDontHaveExecuteRights: ; CODE XREF: WriteProcessMemory+35j
.text:7C8022A2 lea eax, [ebp+nSize]
.text:7C8022A5 push eax
.text:7C8022A6 push 4 ; PAGE_READWRITE
.text:7C8022A8 lea eax, [ebp+lpPageSize]
.text:7C8022AB push eax
.text:7C8022AC lea eax, [ebp+lpPageStartAddress]
.text:7C8022AF push eax
.text:7C8022B0 push edi
.text:7C8022B1 call esi ; NtProtectVirtualMemory
.text:7C8022B3 jmp short lblTestMemoryAccess
.text:7C8022B5 ; ---------------------------------------------------------------------------
.text:7C8022B5
.text:7C8022B5 lblNotMMF_OrShared: ; CODE XREF: WriteProcessMemory+40j
.text:7C8022B5 test al, 3 ; 判断access值:
.text:7C8022B5 ; PAGE_NOACCESS |PAGE_READONLY
.text:7C8022B7 jnz short lblPageNoAccessOrReadOnly ; 跳还是不跳?
.text:7C8022B9 lea eax, [ebp+hProcess]
.text:7C8022BC push eax
.text:7C8022BD push ebx ; nSize
.text:7C8022BE push [ebp+lpBuffer]
.text:7C8022C1 push [ebp+lpBaseAddress]
.text:7C8022C4 push edi ; hProcess
.text:7C8022C5 call ds:NtWriteVirtualMemory ; 写
.text:7C8022CB mov [ebp+lpBuffer], eax
.text:7C8022CE mov eax, [ebp+lpNumberOfBytesWritten]
.text:7C8022D1 test eax, eax
.text:7C8022D3 jz short lblRestoreOldAccess
.text:7C8022D5 mov ecx, [ebp+hProcess]
.text:7C8022D8 mov [eax], ecx
.text:7C8022DA
.text:7C8022DA lblRestoreOldAccess: ; CODE XREF: WriteProcessMemory+C4j
.text:7C8022DA lea eax, [ebp+nSize]
.text:7C8022DD push eax ; &nSize
.text:7C8022DE push [ebp+nSize] ; 恢复旧的access值
.text:7C8022E1 lea eax, [ebp+lpPageSize]
.text:7C8022E4 push eax
.text:7C8022E5 lea eax, [ebp+lpPageStartAddress]
.text:7C8022E8 push eax
.text:7C8022E9 push edi
.text:7C8022EA call esi ; NtProtectVirtualMemory
.text:7C8022EC cmp [ebp+lpBuffer], 0
.text:7C8022F0 jge short lblFlushInstructions
.text:7C8022F2 mov esi, 0C0000005h ; STATUS_ACCESS_VIOLATION
.text:7C8022F7 jmp short lblThrowAccessViolation
if (!WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew,
sizeof(pfnNew), NULL) && (ERROR_NOACCESS == GetLastError())) {
DWORD dwOldProtect;
if (VirtualProtect(ppfn, sizeof(pfnNew), PAGE_WRITECOPY,
&dwOldProtect)) {
WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew,
sizeof(pfnNew), NULL);
VirtualProtect(ppfn, sizeof(pfnNew), dwOldProtect,
&dwOldProtect);
}