VirtualAllocAPi逆向笔记
VirtualAlloc函数简介
VirtualAlloc接口是通过Windows操作系统申请内存页的函数
函数的功能是“保留”或“提交”内存页面,将“空闲的”内存页面变为“保留的”或“已提交的”,将“保留的”页面变为“提交的”
函数原型:
LPVOID __stdcall VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect)
◇参数
lpAddress:输入参数,分配的起始位置。如果是要保留一段内存区域,那么函数会将其自动向最近的一个分配粒度对齐;如果是要提留一段内存区域,那么函数将会向最近的一个页面对齐。 如果为 NULL,那么系统将自行决定在什么地方分配。
dwSize:输入参数,所需要分配的内存区域的大小。
flAllocationType:输入参数,分配的类型,决定了是保留一段内存区域,还是提交,还是同时完成。如果设置为 MEM_COMMIT,那么将提交内存页面;如果设置为 MEM RESERVE,那么将保留页面;如果设置为 MEM_COMMIT∣MEM RESERVED,那么将直接从空闲页面提交为 “已提交的”页面。
flProtect:输入参数,内存的保护属性,其值可以是 PAGE_READWRITE、PAGE_ EXECUTE、PAGE_ EXECUTE READ、PAGE_ EXECUTE READWRITE、PAGE_EXECUTE_WRITECOPY、 PAGE NOACCESS、PAGE WRITECOPY。
◇返回值
返回 LPVOID 类型的值,表示分配到的内存的起始地址。如果返回 NULL,则表示失败。可使用 GetLastError 函数获取错误信息。
在kernel32.dll中的代码分析
此函数使用需要引入windows.h头文件,实际上调用时是调用的kernel32.dll系统文件导出的函数
函数代码如下:
; LPVOID __stdcall VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect)
public VirtualAlloc
VirtualAlloc proc near
lpAddress= dword ptr 8 ;参数1相对ebp的地址
dwSize= dword ptr 0Ch ;参数2相对ebp的地址
flAllocationType= dword ptr 10h ;参数3相对ebp的地址
flProtect= dword ptr 14h ;参数4相对ebp的地址
push ebp ;保存堆栈,并提升堆栈
mov ebp, esp
push [ebp+flProtect] ; flProtect ;压入一系列参数
push [ebp+flAllocationType] ; flAllocationType
push [ebp+dwSize] ; dwSize
push [ebp+lpAddress] ; lpAddress
push 0FFFFFFFFh ; hProcess
call VirtualAllocEx ;调用VirtualAllocEx
pop ebp
retn 10h
VirtualAlloc endp
从上述代码可以看出VirtualAlloc函数实际上是调用的VirtualAllocEx函数并传入自身进程
VirtualAllocEx 函数的作用是在指定进程的虚拟空间保留或提交内存区域,除非指定MEM_RESET参数,否则将该内存区域置0。
原型如下:
LPVOID VirtualAllocEx(
HANDLE hProcess, // 申请内存所在的进程句柄
LPVOID lpAddress, // 保留页面的内存地址;一般用NULL自动分配
SIZE_T dwSize, // 欲分配的内存大小,字节单位;注意实际分 配的内存大小是页内存大小的整数倍
DWORD flAllocationType,
DWORD flProtect
);
VirtualAllocEx在kernel32.dell中的代码
代码如下:
; LPVOID __stdcall VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect)
.text:77E59824 public VirtualAllocEx
.text:77E59824 VirtualAllocEx proc near ; CODE XREF: VirtualAlloc+11↑p
.text:77E59824 ; DATA XREF: .text:off_77E62168↓o
.text:77E59824
.text:77E59824 var_20 = dword ptr -20h
.text:77E59824 var_1C = dword ptr -1Ch
.text:77E59824 ms_exc = CPPEH_RECORD ptr -18h
.text:77E59824 ProcessHandle = dword ptr 8
.text:77E59824 BaseAddress = dword ptr 0Ch
.text:77E59824 RegionSize = dword ptr 10h
.text:77E59824 AllocationType = dword ptr 14h
.text:77E59824 Protect = dword ptr 18h
.text:77E59824
.text:77E59824 ; FUNCTION CHUNK AT .text:77E44CAB SIZE 0000000D BYTES
.text:77E59824 ; FUNCTION CHUNK AT .text:77E82731 SIZE 00000025 BYTES
.text:77E59824
.text:77E59824 ; __unwind { // __SEH_prolog
.text:77E59824 push 10h
.text:77E59826 push offset stru_77E68D90
.text:77E5982B call __SEH_prolog
.text:77E59830 mov eax, [ebp+BaseAddress]
.text:77E59833 test eax, eax
.text:77E59835 jnz short loc_77E5986E
.text:77E59837
.text:77E59837 loc_77E59837: ; CODE XREF: VirtualAllocEx+56↓j
.text:77E59837 ; __try { // __except at loc_77E8274B
.text:77E59837 and [ebp+ms_exc.registration.TryLevel], 0
.text:77E5983B push [ebp+Protect] ; Protect
.text:77E5983E push [ebp+AllocationType] ; AllocationType
.text:77E59841 lea eax, [ebp+RegionSize]
.text:77E59844 push eax ; RegionSize
.text:77E59845 push 0 ; ZeroBits
.text:77E59847 lea eax, [ebp+BaseAddress]
.text:77E5984A push eax ; BaseAddress
.text:77E5984B push [ebp+ProcessHandle] ; ProcessHandle
.text:77E5984E call ds:NtAllocateVirtualMemory
.text:77E59854 mov [ebp+var_1C], eax
.text:77E59854 ; } // starts at 77E59837
.text:77E59857
.text:77E59857 loc_77E59857: ; CODE XREF: VirtualAllocEx+28F2D↓j
.text:77E59857 or [ebp+ms_exc.registration.TryLevel], 0FFFFFFFFh
.text:77E5985B test eax, eax
.text:77E5985D jl loc_77E44CAB
.text:77E59863 mov eax, [ebp+BaseAddress]
.text:77E59866
.text:77E59866 loc_77E59866: ; CODE XREF: VirtualAllocEx-14B71↑j
.text:77E59866 call __SEH_epilog
.text:77E5986B retn 14h
.text:77E5986E ; ---------------------------------------------------------------------------
.text:77E5986E
.text:77E5986E loc_77E5986E: ; CODE XREF: VirtualAllocEx+11↑j
.text:77E5986E mov ecx, dword_77EB603C
.text:77E59874 cmp eax, [ecx+13Ch]
.text:77E5987A jnb short loc_77E59837
.text:77E5987C jmp loc_77E82731
.text:77E5987C ; } // starts at 77E59824
.text:77E5987C VirtualAllocEx endp
上述代码看上去很多实际流程很简单,可以笼统看为下面三步:
- 判断baseaddress参数是否传入
- 压入参数调用函数:NtAllocateVirtualMemory
- 对返回值eax进行判断和返回
通过导入表可以知道NtAllocateVirtualMemory函数为ntdll.dll导出的函数
通过ntdll.dll的导出表可以看到NtAllocateVirtualMemory在ntdll.dll中代码如下
public ZwAllocateVirtualMemory
ZwAllocateVirtualMemory proc near ; CODE XREF: RtlAllocateHeap+1814↑p
; sub_77F53A7C+5F↑p ...
mov eax, 11h ; NtAllocateVirtualMemory
mov edx, 7FFE0300h
call edx
retn 18h
ZwAllocateVirtualMemory endp
可以看到是通过Windows系统内核的数据结构偏移300位置(_KUSER_SHARED_DATA在用户层的地址为7FFE0000h)所存储的地址来调用的实际内核实现,函数编号为11h。
这里不对如何通过系统调用号找到内核实现函数做具体的描述,具体3环进0环可以看我关于系统调用流程描述的笔记(sysenter指令可以通过白皮书第二卷查看具体内容)
这里我们直接通过11h调用号到系统服务表中找到具体的内核实现代码
kd> dd KeServiceDescriptorTable
80545c00 804fd624 00000000 0000011c 804fda98
80545c10 00000000 00000000 00000000 00000000
80545c20 00000000 00000000 00000000 00000000
80545c30 00000000 00000000 00000000 00000000
80545c40 00002710 bf87e0dc 00000000 00000000
80545c50 81dbc0f0 806c6720 00000000 00000000
80545c60 cd3513a3 00000003 a96cc3e3 01d8f354
80545c70 00000000 00000000 00000000 00000000
我们直接看第一个数据结构(第一个为内核函数的服务表导出结构)
804fd624 00000000 0000011c 804fda98 对应:函数地址表,null,函数个数,函数参数表
函数地址表中存储的地址每个占用4个byte所以 所要找的函数地址=函数地址表的首地址+4*函数调用号
804fd624+4*11h
通过windbg查看可以得出如下结果
kd> dd 804fd624+4*11
804fd668 8057ef4b 8054fc3b 805b88cf 8050d5fc
804fd678 8061c934 805b40bc 804e2910 8056eecb
804fd688 805735c1 80560f19 80621f33 80611955
804fd698 80584d84 8062215f 80566287 804d9365
804fd6a8 8062a52b 8059e59a 8057a9e0 8061ce63
804fd6b8 80579edf 80556d7d 805b8237 80608c3e
804fd6c8 80564030 80563111 80583a9f 8056bd3c
804fd6d8 80597e08 80552dbe 8059b61d 80581346
kd> u 8057ef4b
nt!NtAllocateVirtualMemory:
8057ef4b 6800010000 push 100h
8057ef50 6818e84f80 push offset nt!FsRtlLegalAnsiCharacterArray+0xc60 (804fe818)
8057ef55 e8fa0af9ff call nt!strstr+0x80 (8050fa54)
8057ef5a 33f6 xor esi,esi
8057ef5c 8975e4 mov dword ptr [ebp-1Ch],esi
8057ef5f 837d1015 cmp dword ptr [ebp+10h],15h
8057ef63 0f876b2b0500 ja nt!RtlDowncaseUnicodeString+0x11fa7 (805d1ad4)
8057ef69 8b4d18 mov ecx,dword ptr [ebp+18h]
可以得知具体的内核函数名为NtAllocateVirtualMemory
下面看一下代码
内核NtAllocateVirtualMemory函数分析
函数说明:
NtAllocateVirtualMemory 例程保留、提交或同时保留指定进程的用户模式虚拟地址空间中的页面区域。
下面是从ntoskrnl中找到的代码
; ---------------------------------------------------------------------------
PAGE:004ADD60 ; START OF FUNCTION CHUNK FOR NtAllocateVirtualMemory
PAGE:004ADD60
PAGE:004ADD60 loc_4ADD60: ; CODE XREF: NtAllocateVirtualMemory+1DB↓j
PAGE:004ADD60 test byte ptr [ebp+1Dh], 2
PAGE:004ADD64 jnz loc_500EAC
PAGE:004ADD6A test byte ptr [ebp-66h], 40h
PAGE:004ADD6E jnz loc_480D2D
PAGE:004ADD74
PAGE:004ADD74 loc_4ADD74: ; CODE XREF: NtAllocateVirtualMemory-2D201↑j
PAGE:004ADD74 mov eax, [ebx+18h]
PAGE:004ADD77 cmp dword ptr [eax+24h], 0
PAGE:004ADD7B jnz loc_47F048
PAGE:004ADD81 mov eax, [ebx]
PAGE:004ADD83 mov ecx, edx
PAGE:004ADD85 shr ecx, 0Ah
PAGE:004ADD88 and ecx, 3FFFFCh
PAGE:004ADD8E shl eax, 2
PAGE:004ADD91 sub ecx, eax
PAGE:004ADD93 mov eax, [ebx+1Ch]
PAGE:004ADD96 add ecx, eax
PAGE:004ADD98 shr edx, 0Ch
PAGE:004ADD9B cmp ecx, [ebx+20h]
PAGE:004ADD9E ja loc_47D3F6
PAGE:004ADDA4 sub edx, [ebx]
PAGE:004ADDA6 lea eax, [eax+edx*4]
PAGE:004ADDA9
PAGE:004ADDA9 loc_4ADDA9: ; CODE XREF: NtAllocateVirtualMemory-30B4E↑j
PAGE:004ADDA9 mov [ebp-0A8h], eax
PAGE:004ADDAF mov eax, [ebx]
PAGE:004ADDB1 mov ecx, [ebx+1Ch]
PAGE:004ADDB4 shr edi, 0Ah
PAGE:004ADDB7 and edi, 3FFFFCh
PAGE:004ADDBD mov edx, eax
PAGE:004ADDBF shl edx, 2
PAGE:004ADDC2 sub edi, edx
PAGE:004ADDC4 add edi, ecx
PAGE:004ADDC6 mov edx, [ebp-64h]
PAGE:004ADDC9 cmp edi, [ebx+20h]
PAGE:004ADDCC ja loc_47D402
PAGE:004ADDD2 sub edx, eax
PAGE:004ADDD4 lea eax, [ecx+edx*4]
PAGE:004ADDD7
PAGE:004ADDD7 loc_4ADDD7: ; CODE XREF: NtAllocateVirtualMemory-30B42↑j
PAGE:004ADDD7 mov [ebp-0ACh], eax
PAGE:004ADDDD mov eax, [ebp-0A8h]
PAGE:004ADDE3 mov [ebp-0B0h], eax
PAGE:004ADDE9 mov edi, [ebp-0ACh]
PAGE:004ADDEF sub edi, eax
PAGE:004ADDF1 add edi, 4
PAGE:004ADDF4 sar edi, 2
PAGE:004ADDF7 mov [ebp-54h], edi
PAGE:004ADDFA xor eax, eax
PAGE:004ADDFC mov [ebp-0B4h], eax
PAGE:004ADE02 mov ecx, [ebp-20h]
PAGE:004ADE05 and ecx, 5
PAGE:004ADE08 cmp cl, 5
PAGE:004ADE0B jz loc_500C0C
PAGE:004ADE11
PAGE:004ADE11 loc_4ADE11: ; CODE XREF: NtAllocateVirtualMemory+52CC7↓j
PAGE:004ADE11 mov [ebp-0B8h], eax
PAGE:004ADE17 mov [ebp-0BCh], eax
PAGE:004ADE1D cmp [ebp-0B4h], eax
PAGE:004ADE23 jnz loc_500C17
PAGE:004ADE29
PAGE:004ADE29 loc_4ADE29: ; CODE XREF: NtAllocateVirtualMemory+52D2F↓j
PAGE:004ADE29 ; NtAllocateVirtualMemory+52D4E↓j ...
PAGE:004ADE29 mov eax, [ebp-0B4h]
PAGE:004ADE2F lea ecx, [eax+edi]
PAGE:004ADE32 xor edx, edx
PAGE:004ADE34 call sub_41BD93
PAGE:004ADE39 cmp eax, 1
PAGE:004ADE3C jnz loc_500CD0
PAGE:004ADE42 cmp dword ptr [ebp-0B8h], 0
PAGE:004ADE49 jnz short loc_4ADE55
PAGE:004ADE4B mov ecx, offset dword_476220
PAGE:004ADE50 call ExAcquireFastMutexUnsafe
PAGE:004ADE55
PAGE:004ADE55 loc_4ADE55: ; CODE XREF: NtAllocateVirtualMemory-102↑j
PAGE:004ADE55 mov eax, [ebx+18h]
PAGE:004ADE58 mov eax, [eax]
PAGE:004ADE5A mov ecx, [eax+18h]
PAGE:004ADE5D mov [ebp-0C0h], ecx
PAGE:004ADE63 and dword ptr [ebp-0C4h], 0
PAGE:004ADE6A mov ecx, [ebp-0A8h]
PAGE:004ADE70 cmp ecx, [ebp-0ACh]
PAGE:004ADE76 ja short loc_4ADE98
PAGE:004ADE78 mov ecx, [ebp-0B0h]
PAGE:004ADE7E
PAGE:004ADE7E loc_4ADE7E: ; CODE XREF: NtAllocateVirtualMemory-B5↓j
PAGE:004ADE7E cmp dword ptr [ecx], 0
PAGE:004ADE81 jz loc_4B1BC5
PAGE:004ADE87 inc dword ptr [ebp-0C4h]
PAGE:004ADE8D
PAGE:004ADE8D loc_4ADE8D: ; CODE XREF: NtAllocateVirtualMemory+3C82↓j
PAGE:004ADE8D add ecx, 4
PAGE:004ADE90 cmp ecx, [ebp-0ACh]
PAGE:004ADE96 jbe short loc_4ADE7E
PAGE:004ADE98
PAGE:004ADE98 loc_4ADE98: ; CODE XREF: NtAllocateVirtualMemory-D5↑j
PAGE:004ADE98 cmp dword ptr [ebp-0B8h], 0
PAGE:004ADE9F jnz loc_47D40E
PAGE:004ADEA5 sub edi, [ebp-0C4h]
PAGE:004ADEAB mov [ebp-54h], edi
PAGE:004ADEAE
PAGE:004ADEAE loc_4ADEAE: ; CODE XREF: NtAllocateVirtualMemory-30B36↑j
PAGE:004ADEAE test edi, edi
PAGE:004ADEB0 jz short loc_4ADEC0
PAGE:004ADEB2 add [eax+1Ch], edi
PAGE:004ADEB5 mov eax, [ebp-54h]
PAGE:004ADEB8 mov ecx, offset unk_46E8C8
PAGE:004ADEBD xadd [ecx], eax
PAGE:004ADEC0
PAGE:004ADEC0 loc_4ADEC0: ; CODE XREF: NtAllocateVirtualMemory-9B↑j
PAGE:004ADEC0 mov ecx, offset dword_476220
PAGE:004ADEC5 call ExReleaseFastMutexUnsafe
PAGE:004ADECA mov ecx, [ebp-0B4h]
PAGE:004ADED0 test ecx, ecx
PAGE:004ADED2 jnz loc_500C9E
PAGE:004ADED8
PAGE:004ADED8 loc_4ADED8: ; CODE XREF: NtAllocateVirtualMemory+52D78↓j
PAGE:004ADED8 ; NtAllocateVirtualMemory+52D80↓j ...
PAGE:004ADED8 lea eax, [ebp-0A0h]
PAGE:004ADEDE push eax
PAGE:004ADEDF push 1
PAGE:004ADEE1 lea eax, [ebp-0A4h]
PAGE:004ADEE7 push eax
PAGE:004ADEE8 push dword ptr [ebp+1Ch]
PAGE:004ADEEB push dword ptr [ebp-58h]
PAGE:004ADEEE push dword ptr [ebp-5Ch]
PAGE:004ADEF1 push ebx
PAGE:004ADEF2 push esi
PAGE:004ADEF3 call sub_4AC86B
PAGE:004ADEF8 lea ecx, [esi+0F0h] ; FastMutex
PAGE:004ADEFE call ds:ExReleaseFastMutex
PAGE:004ADF04 mov eax, [ebp-0C4h]
PAGE:004ADF0A test eax, eax
PAGE:004ADF0C jnz loc_4972CF
PAGE:004ADF12
PAGE:004ADF12 loc_4ADF12: ; CODE XREF: NtAllocateVirtualMemory-16C66↑j
PAGE:004ADF12 cmp dword ptr [ebp-1Ch], 1
PAGE:004ADF16 jz loc_500D8D
PAGE:004ADF1C
PAGE:004ADF1C loc_4ADF1C: ; CODE XREF: NtAllocateVirtualMemory+52E4B↓j
PAGE:004ADF1C cmp dword ptr [ebp+8], 0FFFFFFFFh
PAGE:004ADF20 jnz loc_500D9B
PAGE:004ADF26
PAGE:004ADF26 loc_4ADF26: ; CODE XREF: NtAllocateVirtualMemory+52E57↓j
PAGE:004ADF26 mov dword ptr [ebp-4], 3
PAGE:004ADF2D mov eax, [ebp-34h]
PAGE:004ADF30 mov ecx, [ebp+14h]
PAGE:004ADF33 mov [ecx], eax
PAGE:004ADF35
PAGE:004ADF35 loc_4ADF35: ; CODE XREF: NtAllocateVirtualMemory+8DC↓j
PAGE:004ADF35 mov eax, [ebp-5Ch]
PAGE:004ADF38 mov ecx, [ebp+0Ch]
PAGE:004ADF3B mov [ecx], eax
PAGE:004ADF3D
PAGE:004ADF3D loc_4ADF3D: ; CODE XREF: sub_500DAB+3↓j
PAGE:004ADF3D or dword ptr [ebp-4], 0FFFFFFFFh
PAGE:004ADF41 xor eax, eax
PAGE:004ADF43
PAGE:004ADF43 loc_4ADF43: ; CODE XREF: NtAllocateVirtualMemory+414↓j
PAGE:004ADF43 ; NtAllocateVirtualMemory+207E↓j ...
PAGE:004ADF43 call sub_43EA8D
PAGE:004ADF48 retn 18h
PAGE:004ADF48 ; END OF FUNCTION CHUNK FOR NtAllocateVirtualMemory
PAGE:004ADF4B ; Exported entry 729. NtAllocateVirtualMemory
PAGE:004ADF4B
PAGE:004ADF4B ; =============== S U B R O U T I N E =======================================
PAGE:004ADF4B
PAGE:004ADF4B
PAGE:004ADF4B ; NTSTATUS __stdcall NtAllocateVirtualMemory(HANDLE ProcessHandle, PVOID *BaseAddress, ULONG_PTR ZeroBits, PSIZE_T RegionSize, ULONG AllocationType, ULONG Protect)
PAGE:004ADF4B public NtAllocateVirtualMemory
PAGE:004ADF4B NtAllocateVirtualMemory proc near ; DATA XREF: .text:0042C668↑o
PAGE:004ADF4B ; .edata:off_5823A8↓o
PAGE:004ADF4B
PAGE:004ADF4B ProcessHandle = dword ptr 4
PAGE:004ADF4B BaseAddress = dword ptr 8
PAGE:004ADF4B ZeroBits = dword ptr 0Ch
PAGE:004ADF4B RegionSize = dword ptr 10h
PAGE:004ADF4B AllocationType = dword ptr 14h
PAGE:004ADF4B Protect = dword ptr 18h
PAGE:004ADF4B
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:0047AD91 SIZE 0000000C BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:0047D3B0 SIZE 00000076 BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:0047EF47 SIZE 00000027 BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:0047F048 SIZE 0000016C BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:0047FB3B SIZE 00000054 BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:00480D2D SIZE 00000022 BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:0048353A SIZE 00000057 BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:004972CF SIZE 0000001B BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:0049E5E9 SIZE 0000001D BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:0049F491 SIZE 00000033 BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:0049F6D9 SIZE 0000001E BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:004ADD60 SIZE 000001EB BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:004AE628 SIZE 00000204 BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:004AFFAB SIZE 00000078 BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:004B1BC5 SIZE 0000000D BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:004DA59F SIZE 00000015 BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:004E71C2 SIZE 0000001D BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:00500AD4 SIZE 00000133 BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:00500C0C SIZE 0000019B BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:00500DB3 SIZE 000000D6 BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:00500EAC SIZE 0000017D BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:0050102E SIZE 00000118 BYTES
PAGE:004ADF4B ; FUNCTION CHUNK AT PAGE:0050114F SIZE 0000001A BYTES
PAGE:004ADF4B
PAGE:004ADF4B push 100h
PAGE:004ADF50 push offset dword_42D818
PAGE:004ADF55 call sub_43EA54
PAGE:004ADF5A xor esi, esi
PAGE:004ADF5C mov [ebp-1Ch], esi
PAGE:004ADF5F cmp dword ptr [ebp+10h], 15h
PAGE:004ADF63 ja loc_500AD4
PAGE:004ADF69 mov ecx, [ebp+18h]
PAGE:004ADF6C test ecx, 0FF87CFFFh
PAGE:004ADF72 jnz loc_500AF9
PAGE:004ADF78 test ecx, 83000h
PAGE:004ADF7E jz loc_500AF9
PAGE:004ADF84 mov eax, 80000h
PAGE:004ADF89 test eax, ecx
PAGE:004ADF8B jnz loc_500ADE
PAGE:004ADF91
PAGE:004ADF91 loc_4ADF91: ; CODE XREF: NtAllocateVirtualMemory+52B97↓j
PAGE:004ADF91 test ecx, 200000h
PAGE:004ADF97 jnz loc_500AE7
PAGE:004ADF9D
PAGE:004ADF9D loc_4ADF9D: ; CODE XREF: NtAllocateVirtualMemory+52BA1↓j
PAGE:004ADF9D test ecx, offset __ImageBase
PAGE:004ADFA3 jnz loc_500AF1
PAGE:004ADFA9
PAGE:004ADFA9 loc_4ADFA9: ; CODE XREF: NtAllocateVirtualMemory+52BBC↓j
PAGE:004ADFA9 mov ecx, [ebp+1Ch]
PAGE:004ADFAC call sub_41AD54
PAGE:004ADFB1 mov [ebp-20h], eax
PAGE:004ADFB4 cmp eax, 0FFFFFFFFh
PAGE:004ADFB7 jz loc_500B17
PAGE:004ADFBD mov [ebp-24h], esi
PAGE:004ADFC0 mov eax, large fs:124h
PAGE:004ADFC6 mov ecx, [eax+44h]
PAGE:004ADFC9 mov [ebp-28h], ecx
PAGE:004ADFCC mov al, [eax+140h]
PAGE:004ADFD2 mov [ebp-2Ch], al
PAGE:004ADFD5 mov [ebp-4], esi
PAGE:004ADFD8 test al, al
PAGE:004ADFDA mov eax, [ebp+0Ch]
PAGE:004ADFDD jz loc_4AE2B0
PAGE:004ADFE3 mov ecx, MmUserProbeAddress
PAGE:004ADFE9 cmp eax, ecx
PAGE:004ADFEB jnb loc_500B21
PAGE:004ADFF1
PAGE:004ADFF1 loc_4ADFF1: ; CODE XREF: NtAllocateVirtualMemory+52BD8↓j
PAGE:004ADFF1 mov ecx, [eax]
PAGE:004ADFF3 mov [eax], ecx
PAGE:004ADFF5 mov edx, [ebp+14h]
PAGE:004ADFF8 mov ecx, MmUserProbeAddress
PAGE:004ADFFE cmp edx, ecx
PAGE:004AE000 jnb loc_500B28
PAGE:004AE006
PAGE:004AE006 loc_4AE006: ; CODE XREF: NtAllocateVirtualMemory+52BDF↓j
PAGE:004AE006 mov ecx, [edx]
PAGE:004AE008 mov [edx], ecx
PAGE:004AE00A
PAGE:004AE00A loc_4AE00A: ; CODE XREF: NtAllocateVirtualMemory+368↓j
PAGE:004AE00A mov ebx, [eax]
PAGE:004AE00C mov [ebp-30h], ebx
PAGE:004AE00F mov edi, [edx]
PAGE:004AE011 mov [ebp-34h], edi
PAGE:004AE014 or dword ptr [ebp-4], 0FFFFFFFFh
PAGE:004AE018 mov eax, MmHighestUserAddress
PAGE:004AE01D lea ecx, [eax-10000h]
PAGE:004AE023 cmp ebx, ecx
PAGE:004AE025 ja loc_500B2F
PAGE:004AE02B mov ecx, eax
PAGE:004AE02D sub ecx, ebx
PAGE:004AE02F sub ecx, 0FFFFh
PAGE:004AE035 cmp ecx, edi
PAGE:004AE037 jb loc_500B39
PAGE:004AE03D cmp edi, esi
PAGE:004AE03F jz loc_500B39
PAGE:004AE045 cmp dword ptr [ebp+8], 0FFFFFFFFh
PAGE:004AE049 jnz loc_4AFFAB
PAGE:004AE04F mov esi, [ebp-28h]
PAGE:004AE052
PAGE:004AE052 loc_4AE052: ; CODE XREF: NtAllocateVirtualMemory+209F↓j
PAGE:004AE052 and dword ptr [ebp-54h], 0
PAGE:004AE056 test ebx, ebx
PAGE:004AE058 jz loc_4AE628
PAGE:004AE05E test byte ptr [ebp+19h], 20h
PAGE:004AE062 jnz loc_4AE628
PAGE:004AE068 cmp dword ptr [ebp+18h], 80000h
PAGE:004AE06F jz loc_500B43
PAGE:004AE075 lea eax, [edi+ebx-1]
PAGE:004AE079 or eax, 0FFFh
PAGE:004AE07E mov [ebp-58h], eax
PAGE:004AE081 mov eax, ebx
PAGE:004AE083 and eax, 0FFFFF000h
PAGE:004AE088 mov [ebp-5Ch], eax
PAGE:004AE08B mov edi, [ebp-58h]
PAGE:004AE08E
PAGE:004AE08E loc_4AE08E: ; CODE XREF: NtAllocateVirtualMemory+52C12↓j
PAGE:004AE08E mov ecx, edi
PAGE:004AE090 sub ecx, eax
PAGE:004AE092 inc ecx
PAGE:004AE093 mov [ebp-34h], ecx
PAGE:004AE096 lea ecx, [esi+0F0h] ; FastMutex
PAGE:004AE09C call ds:ExAcquireFastMutex
PAGE:004AE0A2 test byte ptr [esi+248h], 20h
PAGE:004AE0A9 jnz loc_500B6F
PAGE:004AE0AF mov [ebp-64h], edi
PAGE:004AE0B2 shr dword ptr [ebp-64h], 0Ch
PAGE:004AE0B6 push dword ptr [esi+11Ch]
PAGE:004AE0BC push dword ptr [ebp-64h]
PAGE:004AE0BF mov eax, [ebp-5Ch]
PAGE:004AE0C2 shr eax, 0Ch
PAGE:004AE0C5 push eax
PAGE:004AE0C6 call sub_4AA51F
PAGE:004AE0CB mov ebx, eax
PAGE:004AE0CD test ebx, ebx
PAGE:004AE0CF jz loc_47AD91
PAGE:004AE0D5 mov eax, [ebx+14h]
PAGE:004AE0D8 mov [ebp-68h], eax
PAGE:004AE0DB test eax, 200000h
PAGE:004AE0E0 jnz loc_47AD91
PAGE:004AE0E6 mov edx, [ebp-5Ch]
PAGE:004AE0E9 mov eax, edx
PAGE:004AE0EB shr eax, 0Ch
PAGE:004AE0EE cmp eax, [ebx]
PAGE:004AE0F0 jb loc_47AD91
PAGE:004AE0F6 mov ecx, [ebx+4]
PAGE:004AE0F9 cmp [ebp-64h], ecx
PAGE:004AE0FC ja loc_47AD91
PAGE:004AE102 mov eax, [ebp-68h]
PAGE:004AE105 and eax, 7FFFFh
PAGE:004AE10A cmp eax, 7FFFFh
PAGE:004AE10F jz loc_47AD91
PAGE:004AE115 cmp dword ptr [ebp+18h], 80000h
PAGE:004AE11C jz loc_500B7B
PAGE:004AE122 test byte ptr [ebp-65h], 80h
PAGE:004AE126 jz loc_4ADD60
PAGE:004AE12C test byte ptr [ebp+1Ch], 88h
PAGE:004AE130 jnz loc_500EAC
PAGE:004AE136 mov edi, [ebp-20h]
PAGE:004AE139 shl edi, 5
PAGE:004AE13C mov eax, ds:Pattern
PAGE:004AE141 xor edi, eax
PAGE:004AE143 and edi, 3E0h
PAGE:004AE149 xor edi, eax
PAGE:004AE14B mov [ebp-0C0h], edi
PAGE:004AE151 and eax, 0FFFFFE1Fh
PAGE:004AE156 or eax, 200h
PAGE:004AE15B mov [ebp-0CCh], eax
PAGE:004AE161 test byte ptr [ebp-65h], 40h
PAGE:004AE165 jnz loc_500DB3
PAGE:004AE16B and dword ptr [ebp-0D0h], 0
PAGE:004AE172
PAGE:004AE172 loc_4AE172: ; CODE XREF: NtAllocateVirtualMemory+52E7B↓j
PAGE:004AE172 mov eax, edx
PAGE:004AE174 shr eax, 14h
PAGE:004AE177 and eax, 0FFCh
PAGE:004AE17C sub eax, 3FD00000h
PAGE:004AE181 mov [ebp-0D4h], eax
PAGE:004AE187 shr edx, 0Ah
PAGE:004AE18A mov ecx, 3FFFFCh
PAGE:004AE18F and edx, ecx
PAGE:004AE191 mov eax, 40000000h
PAGE:004AE196 sub edx, eax
PAGE:004AE198 mov [ebp-0B0h], edx
PAGE:004AE19E mov edi, [ebp-58h]
PAGE:004AE1A1 shr edi, 0Ah
PAGE:004AE1A4 and edi, ecx
PAGE:004AE1A6 sub edi, eax
PAGE:004AE1A8 mov [ebp-0ACh], edi
PAGE:004AE1AE sub edi, edx
PAGE:004AE1B0 add edi, 4
PAGE:004AE1B3 sar edi, 2
PAGE:004AE1B6 and dword ptr [ebp-0B8h], 0
PAGE:004AE1BD
PAGE:004AE1BD loc_4AE1BD: ; CODE XREF: NtAllocateVirtualMemory+52EFA↓j
PAGE:004AE1BD and dword ptr [ebp-0BCh], 0
PAGE:004AE1C4 mov eax, [esi+1E8h]
PAGE:004AE1CA test eax, eax
PAGE:004AE1CC jnz loc_4DA59F
PAGE:004AE1D2
PAGE:004AE1D2 loc_4AE1D2: ; CODE XREF: NtAllocateVirtualMemory+2C65E↓j
PAGE:004AE1D2 test byte ptr [esi+244h], 10h
PAGE:004AE1D9 jnz loc_4E71C2
PAGE:004AE1DF
PAGE:004AE1DF loc_4AE1DF: ; CODE XREF: NtAllocateVirtualMemory+3928F↓j
PAGE:004AE1DF xor edx, edx
PAGE:004AE1E1 mov ecx, edi
PAGE:004AE1E3 call sub_41BD93
PAGE:004AE1E8 test eax, eax
PAGE:004AE1EA jz loc_500DD9
PAGE:004AE1F0 push edi
PAGE:004AE1F1 push esi
PAGE:004AE1F2 call sub_422ADD
PAGE:004AE1F7 mov [ebp-60h], eax
PAGE:004AE1FA test eax, eax
PAGE:004AE1FC jl loc_500DE2
PAGE:004AE202 mov eax, [ebx+14h]
PAGE:004AE205 lea ecx, [eax+edi]
PAGE:004AE208 xor ecx, eax
PAGE:004AE20A and ecx, 7FFFFh
PAGE:004AE210 xor ecx, eax
PAGE:004AE212 mov [ebx+14h], ecx
PAGE:004AE215 lea eax, [esi+0A8h]
PAGE:004AE21B add [eax], edi
PAGE:004AE21D mov eax, [eax]
PAGE:004AE21F lea ecx, [esi+1ECh]
PAGE:004AE225 cmp eax, [ecx]
PAGE:004AE227 jbe short loc_4AE22B
PAGE:004AE229 mov [ecx], eax
PAGE:004AE22B
PAGE:004AE22B loc_4AE22B: ; CODE XREF: NtAllocateVirtualMemory+2DC↑j
PAGE:004AE22B ; NtAllocateVirtualMemory+52F00↓j
PAGE:004AE22B and dword ptr [ebp-0C4h], 0
PAGE:004AE232 cmp dword ptr [ebp-0B8h], 0
PAGE:004AE239 jnz short loc_4AE24D
PAGE:004AE23B lea ecx, [esi+0CCh]
PAGE:004AE241 call ExAcquireFastMutexUnsafe
PAGE:004AE246 mov byte ptr [esi+255h], 88h
PAGE:004AE24D
PAGE:004AE24D loc_4AE24D: ; CODE XREF: NtAllocateVirtualMemory+2EE↑j
PAGE:004AE24D push 0
PAGE:004AE24F push esi
PAGE:004AE250 push dword ptr [ebp-0D4h]
PAGE:004AE256 call sub_423C82
PAGE:004AE25B mov edi, [ebp-0B0h]
PAGE:004AE261
PAGE:004AE261 loc_4AE261: ; CODE XREF: NtAllocateVirtualMemory+363↓j
PAGE:004AE261 cmp edi, [ebp-0ACh]
PAGE:004AE267 ja loc_4AE2EE
PAGE:004AE26D test di, 0FFFh
PAGE:004AE272 jz loc_49E5E9
PAGE:004AE278
PAGE:004AE278 loc_4AE278: ; CODE XREF: NtAllocateVirtualMemory-F94A↑j
PAGE:004AE278 mov eax, [edi]
PAGE:004AE27A test eax, eax
PAGE:004AE27C jnz loc_49F491
PAGE:004AE282 cmp edi, [ebp-0D0h]
PAGE:004AE288 jbe loc_500E67
PAGE:004AE28E
PAGE:004AE28E loc_4AE28E: ; CODE XREF: NtAllocateVirtualMemory+52F22↓j
PAGE:004AE28E mov eax, edi
PAGE:004AE290 shl eax, 0Ah
PAGE:004AE293 shr eax, 16h
PAGE:004AE296 mov ecx, dword_4757D0
PAGE:004AE29C lea eax, [ecx+eax*2+3Ch]
PAGE:004AE2A0 inc word ptr [eax]
PAGE:004AE2A3
PAGE:004AE2A3 loc_4AE2A3: ; CODE XREF: NtAllocateVirtualMemory-EAB4↑j
PAGE:004AE2A3 mov eax, [ebp-0C0h]
PAGE:004AE2A9 mov [edi], eax
PAGE:004AE2AB
PAGE:004AE2AB loc_4AE2AB: ; CODE XREF: NtAllocateVirtualMemory-EAA4↑j
PAGE:004AE2AB ; NtAllocateVirtualMemory-EA92↑j ...
PAGE:004AE2AB add edi, 4
PAGE:004AE2AE jmp short loc_4AE261
PAGE:004AE2B0 ; ---------------------------------------------------------------------------
PAGE:004AE2B0
PAGE:004AE2B0 loc_4AE2B0: ; CODE XREF: NtAllocateVirtualMemory+92↑j
PAGE:004AE2B0 mov edx, [ebp+14h]
PAGE:004AE2B3 jmp loc_4AE00A
PAGE:004AE2B8 ; ---------------------------------------------------------------------------
PAGE:004AE2B8
PAGE:004AE2B8 loc_4AE2B8: ; CODE XREF: sub_4AC86B+143↑j
PAGE:004AE2B8 mov eax, ebx
PAGE:004AE2BA shr eax, 0Ch
PAGE:004AE2BD and eax, 3FFh
PAGE:004AE2C2 mov ecx, dword_4757D0
PAGE:004AE2C8 lea eax, [ecx+eax*2+3Ch]
PAGE:004AE2CC inc word ptr [eax]
PAGE:004AE2CF mov eax, [ebp-24h]
PAGE:004AE2D2 shl eax, 5
PAGE:004AE2D5 mov ecx, dword_46C758
PAGE:004AE2DB xor eax, ecx
PAGE:004AE2DD and eax, 3E0h
PAGE:004AE2E2 xor eax, ecx
PAGE:004AE2E4 mov [ebp-40h], eax
PAGE:004AE2E7
PAGE:004AE2E7 loc_4AE2E7: ; CODE XREF: sub_4AC86B+556C0↓j
PAGE:004AE2E7 mov [ebx], eax
PAGE:004AE2E9 jmp loc_4ACAB5
PAGE:004AE2EE ; ---------------------------------------------------------------------------
PAGE:004AE2EE
PAGE:004AE2EE loc_4AE2EE: ; CODE XREF: NtAllocateVirtualMemory+31C↑j
PAGE:004AE2EE and byte ptr [esi+255h], 0
PAGE:004AE2F5 lea ecx, [esi+0CCh]
PAGE:004AE2FB call ExReleaseFastMutexUnsafe
PAGE:004AE300 cmp dword ptr [ebp-0B8h], 0
PAGE:004AE307 jnz short loc_4AE317
PAGE:004AE309 mov edi, [ebp-0C4h]
PAGE:004AE30F test edi, edi
PAGE:004AE311 jnz loc_48353A
PAGE:004AE317
PAGE:004AE317 loc_4AE317: ; CODE XREF: NtAllocateVirtualMemory+3BC↑j
PAGE:004AE317 ; NtAllocateVirtualMemory+52C62↓j
PAGE:004AE317 lea ecx, [esi+0F0h] ; FastMutex
PAGE:004AE31D call ds:ExReleaseFastMutex
PAGE:004AE323
PAGE:004AE323 loc_4AE323: ; CODE XREF: NtAllocateVirtualMemory-2A9C5↑j
PAGE:004AE323 ; NtAllocateVirtualMemory+52F39↓j
PAGE:004AE323 cmp dword ptr [ebp-24h], 0
PAGE:004AE327 jnz loc_500BB2
PAGE:004AE32D
PAGE:004AE32D loc_4AE32D: ; CODE XREF: NtAllocateVirtualMemory+52C97↓j
PAGE:004AE32D cmp dword ptr [ebp-1Ch], 1
PAGE:004AE331 jz loc_4B0009
PAGE:004AE337
PAGE:004AE337 loc_4AE337: ; CODE XREF: NtAllocateVirtualMemory+20C7↓j
PAGE:004AE337 cmp dword ptr [ebp+8], 0FFFFFFFFh
PAGE:004AE33B jnz loc_4B0017
PAGE:004AE341
PAGE:004AE341 loc_4AE341: ; CODE XREF: NtAllocateVirtualMemory+20D3↓j
PAGE:004AE341 mov dword ptr [ebp-4], 4
PAGE:004AE348 mov eax, [ebp+14h]
PAGE:004AE34B mov ecx, [ebp-34h]
PAGE:004AE34E mov [eax], ecx
PAGE:004AE350 mov eax, [ebp-5Ch]
PAGE:004AE353 mov ecx, [ebp+0Ch]
PAGE:004AE356 mov [ecx], eax
PAGE:004AE358 or dword ptr [ebp-4], 0FFFFFFFFh
PAGE:004AE35C
PAGE:004AE35C loc_4AE35C: ; CODE XREF: NtAllocateVirtualMemory-2EFF6↑j
PAGE:004AE35C ; NtAllocateVirtualMemory+53219↓j
PAGE:004AE35C mov eax, [ebp-60h]
PAGE:004AE35F jmp loc_4ADF43
上述代码看上去很多分枝条件很难理解,他的流程其实并不复杂,简单描述他的流程如下:
NtAllocateVirtualMemory(hProcess, void** BaseAddr, int* Len, AllocType, protect)
{
If(参数不合法)//一般SST中的内核服务函数入口处都会对用户空间传下来的参数进行合法性检查
Return fail;
...//获得该进程对象的内核结构
Type=...//判断提交型分配或预定型分配
useraddr=...//获取该进程的用户地址空间
If(*BaseAddr!=NULL)//if 用户给定了分配的起始地址,必须从那儿分配
{
MEMORY_AREA* Area=MmLocateMemoryAreaByAddress(As,*BaseAddr);
If(Area!=NULL)//如果该地址落在事先已经分配的某个页框中
{
//如果用户要求分配的这块区域完全落在那个已分配页框中,就修改分配类型、保护属性
//执行合并、拆分、修改页面映射等相关工作
}
}
//若用户没指定地址,或者即使指定了地址,但那个地址尚未落入任何已分配页框中,就分配页框
//每个页框初始分配时,内部就初始化为:包含一个页。
Return succ;
}//end
简要来说内核所做的事就是如下几步:
- 找到进程内核结构
- 通过段页管理的一棵AVL数进行判断baseaddr是否可以分配
- 为baseaddr线性地址所对应的页分配物理地址
其实从这里可以看出,内核所做的无非是修改内核所保留的一系列内核所保存的系统状态的数据,通过修改内核的数据就可以达到用户在应用层所看到的操作系统表现的变化。