最近在分析某公司DLP产品,里边文档控制相关功能,出于好奇分析了一下原理。
应用层的权限控制一般通过全局Hook注入DLL进行权限控制,使用工具PCHunder发现,除了WH_KEYBOARD_LL消息Hook,没有其它消息Hook,最后通过PCHunder发现是通过驱动层进行设置PsSetCreateProcessNotifyRoutine回调注入Shellcode实现。
具体IDA分析如下图:
bool __stdcall sub_15D40(HANDLE ProcessHandle, wchar_t *wzDllPath)
{
int v3; // [sp+0h] [bp-488h]@21
int v4; // [sp+4h] [bp-484h]@11
char v5; // [sp+8h] [bp-480h]@11
int v6; // [sp+14h] [bp-474h]@12
int v7; // [sp+18h] [bp-470h]@13
unsigned __int8 v8; // [sp+240h] [bp-248h]@2
int v9; // [sp+241h] [bp-247h]@2
unsigned __int8 v10; // [sp+245h] [bp-243h]@2
int v11; // [sp+246h] [bp-242h]@2
unsigned __int16 v12; // [sp+24Ah] [bp-23Eh]@2
int v13; // [sp+24Ch] [bp-23Ch]@2
int v14; // [sp+250h] [bp-238h]@2
int v15; // [sp+254h] [bp-234h]@3
__int16 v16; // [sp+25Dh] [bp-22Bh]@5
__int16 v17; // [sp+25Fh] [bp-229h]@5
int v18; // [sp+261h] [bp-227h]@5
wchar_t v19; // [sp+265h] [bp-223h]@5
int v20; // [sp+46Dh] [bp-1Bh]@5
int v21; // [sp+471h] [bp-17h]@5
unsigned __int8 v22; // [sp+478h] [bp-10h]@8
int v23; // [sp+479h] [bp-Fh]@11
bool v24; // [sp+483h] [bp-5h]@1
int v25; // [sp+484h] [bp-4h]@1
v24 = 0;
v25 = (int)MyAllocateVirtualMemory(ProcessHandle, 0x2BBu, 0);
if ( v25 )
{
v8 = 0xB8u; // MOV EAX,XXXXXXXX
v9 = v25;
v10 = 0xB9u; // MOV ECX,XXXXXXXX
v11 = v25 + 565;
v12 = 0xD1FFu; // CALL ECX
v13 = 0x4C69636D; // 特征码
v14 = 0;
v15 = pfnNtTestAlert ? pfnNtTestAlert : sub_15570(ProcessHandle);
v16 = 2 * wcslen(wzDllPath); // UNICODE_STRING ++0 Length
v17 = v16 + 2; // UNICODE_STRING ++2 MaxmumLength
v18 = v25 + 0x25; // UNICODE_STRING ++4 Buffer
wcscpy(&v19, wzDllPath); // 将wzDllPath拷贝进ShellCode
v20 = pfnNtProtectVirtualMemory;
v21 = pfnLdrLoadDll;
if ( v15 )
{
if ( MyWriteVirtualMemory((int)ProcessHandle, v25, (int)&v8, 566)
&& MyWriteVirtualMemory((int)ProcessHandle, v25 + 0x235, (int)sub_10420, 133)
&& MyReadVirtualMemory((int)ProcessHandle, v15, (int)&v22, 5)// 读取pfnNtTestAlert函数前5个字节备份到ShellCode中
&& MyWriteVirtualMemory((int)ProcessHandle, v25 + 0x18, (int)&v22, 5) )
{
if ( v22 == 0xE9 ) // 构造要插入dll的链表ShellCode
{
v4 = v15 + v23 + 5;
if ( MyReadVirtualMemory((int)ProcessHandle, v4, (int)&v5, 566) && v6 == 0x4C69636D )
{
while ( v7 )
{
v4 = v7;
if ( !MyReadVirtualMemory((int)ProcessHandle, v7, (int)&v5, 566) || v6 != 0x4C69636D )
{
v4 = 0;
break;
}
}
if ( v4 )
{
v7 = v25;
v24 = MyWriteVirtualMemory((int)ProcessHandle, v4, (int)&v5, 566);
}
}
}
if ( !v24 && MyProtectVirutalMemory((int)ProcessHandle, v15, 5, 64, (int)&v3) )// 修改pfnNtTestAlert函数前面5个字节为jmp XXXX,其中XXXX为Shellcode入口地址
{
v22 = 0xE9u;
v23 = v25 - v15 - 5;
MyWriteVirtualMemory((int)ProcessHandle, v15, (int)&v22, 5);
MyProtectVirutalMemory((int)ProcessHandle, v15, 5, v3, (int)&v3);
v24 = 1;
}
}
}
}
return v24;
}
使用Windbg 启动notepad,反汇编发现ntdll!NtTestAlert函数前5个字节被修改为jmp指令,随后将jmp位置的内存进行转储分析如下:
seg000:00000000 seg000 segment byte public 'CODE' use32
seg000:00000000 assume cs:seg000
seg000:00000000 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg000:00000000 mov eax, 40000h
seg000:00000005
seg000:00000005 loc_5:
seg000:00000005 mov ecx, 40235h
seg000:0000000A call ecx
seg000:0000000A ; ---------------------------------------------------------------------------
seg000:0000000C dd 4C69636Dh ; 特征码
seg000:00000010 dd 0 ; 下一个ShellCode地址
seg000:00000014 dd 76EC5D30h ; pfnNtTestAlert
seg000:00000018 ; ---------------------------------------------------------------------------
seg000:00000018 mov eax, 174h
seg000:00000018 ; ---------------------------------------------------------------------------
seg000:0000001D UNICODE_STRING <5Eh, 60h, 40025h>
seg000:00000025 aCProgramFilesM:
seg000:00000025 unicode 0, <C:\Program Files\XXXXX\DLP\Agent\fcagcbh32.dll>,0
....
seg000:0000022D dd 76EC5360h ; pfnNtProtectVirtualMemory
seg000:00000231 dd 76EDF585h ; pfnLdrLoadDll
seg000:00000235
seg000:00000235 ; =============== S U B R O U T I N E =======================================
seg000:00000235
seg000:00000235 ; Attributes: bp-based frame
seg000:00000235
seg000:00000235 sub_235 proc near
seg000:00000235
seg000:00000235 var_C = dword ptr -0Ch
seg000:00000235 var_8 = dword ptr -8
seg000:00000235 var_4 = dword ptr -4
seg000:00000235
seg000:00000235 push ebp
seg000:00000236 mov ebp, esp
seg000:00000238 add esp, 0FFFFFFF4h
seg000:0000023B push ebx
seg000:0000023C mov ebx, eax ; 参数基址
seg000:0000023E mov [ebp+var_4], ebp
seg000:00000241 mov eax, [ebp+var_4]
seg000:00000244 add eax, 4 ; 指向栈上函数返回地址
seg000:00000247 mov edx, [ebx+14h]
seg000:0000024A mov [eax], edx ; 修改函数返回地址为pfnNtTestAlert
seg000:0000024C mov eax, [ebx+14h]
seg000:0000024F mov [ebp+var_C], eax
seg000:00000252 mov [ebp+var_4], 5
seg000:00000259 lea eax, [ebp+var_8]
seg000:0000025C push eax ; OldProtect
seg000:0000025D push 40h ; '@' ; PAGE_EXECUTE_READWRITE
seg000:0000025F lea eax, [ebp+var_4]
seg000:00000262 push eax ; RegionSize
seg000:00000263 lea eax, [ebp+var_C]
seg000:00000266 push eax ; BaseAddress
seg000:00000267 push 0FFFFFFFFh ; ProcessHandle
seg000:00000269 call dword ptr [ebx+22Dh] ; NtProtectVirtualMemory
seg000:0000026F mov eax, [ebx+14h]
seg000:00000272 mov edx, [ebx+18h]
seg000:00000275 mov [eax], edx
seg000:00000277 mov dl, [ebx+1Ch] ; 修改NtTestAlert函数前5个字节为MOV EAX, 174h
seg000:0000027A mov [eax+4], dl
seg000:0000027D mov [ebp+var_4], 5
seg000:00000284 lea eax, [ebp+var_8]
seg000:00000287 push eax ; OldProtect
seg000:00000288 mov eax, [ebp+var_8]
seg000:0000028B push eax ; NewProtectWin32
seg000:0000028C lea eax, [ebp+var_4]
seg000:0000028F push eax ; RegionSize
seg000:00000290 lea eax, [ebp+var_C]
seg000:00000293 push eax ; BaseAddress
seg000:00000294 push 0FFFFFFFFh ; ProcessHandle
seg000:00000296 call dword ptr [ebx+22Dh] ; NtProtectVirtualMemory
seg000:0000029C
seg000:0000029C loc_29C: ; CODE XREF: sub_235+7Ej
seg000:0000029C lea eax, [ebp+var_4]
seg000:0000029F push eax
seg000:000002A0 lea eax, [ebx+1Dh]
seg000:000002A3 push eax
seg000:000002A4 push 0
seg000:000002A6 push 0
seg000:000002A8 call dword ptr [ebx+231h] ; LdrLoadDll
seg000:000002AE mov ebx, [ebx+10h]
seg000:000002B1 test ebx, ebx
seg000:000002B3 jnz short loc_29C
seg000:000002B5 pop ebx
seg000:000002B6 mov esp, ebp
seg000:000002B8 pop ebp
seg000:000002B9 retn
seg000:000002B9 sub_235 endp
seg000:000002B9
seg000:000002B9 ; ---------------------------------------------------------------------------
seg000:000002BA align 1000h
seg000:000002BA seg000 ends
seg000:000002BA
seg000:000002BA
seg000:000002BA end
最后总结一下原理:
1、驱动通过函数PsSetCreateProcessNotifyRoutine对新启动的进程进行监控(Win8 以后机器需要额外调用PsSetLoadImageNotifyRoutine设置回调)。
2、在ProcessCreate回调中对启动的进程插入ShellCode。
3、修改启动进程ntdll函数NtTestAlert入口5字节为jmp指令跳转到ShellCode开始地址进行执行。
4、进程的主线程开始执行调用ntdll!LdrInitializeThunk->ntdll!_LdrpInitialize->ntdll!NtTestAlert函数触发Shellcode执行。
5、ShellCode执行通过调用ntdll!LdrLoadDll函数装入DLL并且修改ShellCode的返回地址为NtTestAlert,还原NtTestAlert函数的前5个字节内容,正式
执行NtTestAlert函数。
6、后续NtTestAlert函数的调用不再会触发ShellCode的执行。
在Win64环境启动64位程序,注入的ShellCode工作原理与32位的类似,上传ShellCode分析代码如下:
seg000:0000000000000000 seg000 segment byte public 'CODE' use64
seg000:0000000000000000 assume cs:seg000
seg000:0000000000000000 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg000:0000000000000000 mov rax, 77622B20h
seg000:000000000000000A push rax ; ShellCode执行完返回地址
seg000:000000000000000B push rcx
seg000:000000000000000C push rdx
seg000:000000000000000D push r8
seg000:000000000000000F push r9
seg000:0000000000000011 sub rsp, 28h
seg000:0000000000000015 mov rcx, 71B00000h ; 该ShellCode加载基址
seg000:000000000000001F mov rdx, 71B0026Ch
seg000:0000000000000029 jmp rdx
seg000:0000000000000029 ; ---------------------------------------------------------------------------
seg000:000000000000002B dd 4C69636Dh ; 特征码
seg000:000000000000002F qword_2F dq 0
seg000:0000000000000037 dq 77622B20h ; pfnNtTestAlert
seg000:000000000000003F db 4Ch ; L ; NtTestAlert函数前5个字节备份
seg000:0000000000000040 db 8Bh ;
seg000:0000000000000041 db 0D1h ;
seg000:0000000000000042 db 0B8h ;
seg000:0000000000000043 db 7Eh ; ~
seg000:0000000000000044 dw 5Eh ; UNICODE_STRING ++0 Length
seg000:0000000000000046 dw 60h ; UNICODE_STRING ++2 MaximumLength
seg000:0000000000000048 dd 0 ; UNICODE_STRING x64 align padding
seg000:000000000000004C dq 71B00054h ; UNICODE_STRING ++8 Buffer
seg000:0000000000000054 aCProgramFilesM:
seg000:0000000000000054 unicode 0, <C:\Program Files\XXXXXX\DLP\Agent\fcagcbh64.dll>,0
。。。。省略无效
seg000:000000000000025C dq 77621810h ; pfnNtProtectVirtualMemory
seg000:0000000000000264 dq 775F7A90h ; pfnNtLdrLoadDll
seg000:000000000000026C
seg000:000000000000026C ; =============== S U B R O U T I N E =======================================
seg000:000000000000026C
seg000:000000000000026C
seg000:000000000000026C sub_26C proc near
seg000:000000000000026C
seg000:000000000000026C var_18 = qword ptr -18h
seg000:000000000000026C arg_0 = dword ptr 8
seg000:000000000000026C arg_8 = qword ptr 10h
seg000:000000000000026C arg_10 = byte ptr 18h
seg000:000000000000026C
seg000:000000000000026C mov r11, rsp
seg000:000000000000026F push rbx
seg000:0000000000000270 sub rsp, 30h
seg000:0000000000000274 mov rax, [rcx+37h] ; rax<-pfnNtTestAlert
seg000:0000000000000278 mov rbx, rcx
seg000:000000000000027B lea r8, [r11+10h] ; RegionSize
seg000:000000000000027F mov [r11+18h], rax
seg000:0000000000000283 lea rax, [r11+8]
seg000:0000000000000287 lea rdx, [r11+18h] ; BaseAddress
seg000:000000000000028B mov r9d, 40h ; '@' ; NewProtect
seg000:0000000000000291 or rcx, 0FFFFFFFFFFFFFFFFh ; ProcessHandle
seg000:0000000000000295 mov qword ptr [r11+10h], 5
seg000:000000000000029D mov [r11-18h], rax
seg000:00000000000002A1 call qword ptr [rbx+25Ch] ; pfnNtProtectVirtualMemory
seg000:00000000000002A7 test eax, eax
seg000:00000000000002A9 jnz short loc_2E8
seg000:00000000000002AB mov eax, [rbx+3Fh] ; NtTestAlert前4个字节放到eax中
seg000:00000000000002AE mov rdx, [rbx+37h] ; rdx<-pfnNtTestAlert
seg000:00000000000002B2 lea r8, [rsp+38h+arg_8] ; RegionSize
seg000:00000000000002B7 mov [rdx], eax ; 重写函数NtTestAlert前4个字节
seg000:00000000000002B9 mov al, [rbx+43h] ; 获取备份的第5个字节
seg000:00000000000002BC or rcx, 0FFFFFFFFFFFFFFFFh ; ProcessHandle
seg000:00000000000002C0 mov [rdx+4], al ; 重写函数NtTestAlert第5个字节
seg000:00000000000002C3 mov r9d, [rsp+38h+arg_0]
seg000:00000000000002C8 lea rax, [rsp+38h+arg_0]
seg000:00000000000002CD lea rdx, [rsp+38h+arg_10]
seg000:00000000000002D2 mov [rsp+38h+var_18], rax
seg000:00000000000002D7 mov [rsp+38h+arg_8], 5
seg000:00000000000002E0 call qword ptr [rbx+25Ch] ; pfnNtProtectVirtualMemory
seg000:00000000000002E6 jmp short loc_30F ; ModuleFileName
seg000:00000000000002E8 ; ---------------------------------------------------------------------------
seg000:00000000000002E8
seg000:00000000000002E8 loc_2E8: ; CODE XREF: sub_26C+3Dj
seg000:00000000000002E8 mov rax, [rbx+37h]
seg000:00000000000002EC mov rcx, [rax] ; 将当前内存pfnNtTestAlert前8个字节放入rcx
seg000:00000000000002EF mov eax, [rbx+3Fh] ; 将备份的pfnNtTestAlert前4个字节放入eax
seg000:00000000000002F2 mov [rbx], rcx
seg000:00000000000002F5 mov [rbx], eax
seg000:00000000000002F7 mov al, [rbx+43h]
seg000:00000000000002FA mov [rbx+4], al
seg000:00000000000002FD lea rcx, [rbx+8]
seg000:0000000000000301 mov byte ptr [rcx], 0E9h ; ' ; 修改ShellCode入口代码,第一条语句为NtTestAlert函数第一条语句,第二条语句跳回NtTestAlert函数的第二条语句
seg000:0000000000000304 mov eax, [rbx+37h]
seg000:0000000000000307 sub eax, ecx
seg000:0000000000000309 add eax, 3
seg000:000000000000030C mov [rcx+1], eax
seg000:000000000000030F
seg000:000000000000030F loc_30F: ; CODE XREF: sub_26C+7Aj
seg000:000000000000030F ; sub_26C+BDj
seg000:000000000000030F lea r8, [rbx+44h] ; ModuleFileName
seg000:0000000000000313 lea r9, [rsp+38h+arg_8] ; ModuleHandle
seg000:0000000000000318 xor edx, edx ; Flags
seg000:000000000000031A xor ecx, ecx ; PathToFile
seg000:000000000000031C call qword ptr [rbx+264h] ; call NtTestAlert
seg000:0000000000000322 mov rbx, [rbx+2Fh]
seg000:0000000000000326 test rbx, rbx
seg000:0000000000000329 jnz short loc_30F ; ModuleFileName
seg000:000000000000032B add rsp, 30h
seg000:000000000000032F pop rbx
seg000:0000000000000330 add rsp, 28h
seg000:0000000000000334 pop r9
seg000:0000000000000336 pop r8
seg000:0000000000000338 pop rdx
seg000:0000000000000339 pop rcx
seg000:000000000000033A retn
使用64位驱动注入ShellCode到32位应用程序Hook的是ntdll32!NtTestAlert函数,上传ShellCode分析代码。
seg000:00000000 seg000 segment byte public 'CODE' use32
seg000:00000000 assume cs:seg000
seg000:00000000 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg000:00000000 mov eax, 80000h ; ShellCode加载基址
seg000:00000005
seg000:00000005 loc_5:
seg000:00000005 mov ecx, 80235h
seg000:0000000A call ecx
seg000:0000000A ; ---------------------------------------------------------------------------
seg000:0000000C dd 4C69636Dh ; 特征码
seg000:00000010 dd 0
seg000:00000014 dd 777D1DB0h ; pfnNtTestAlert
seg000:00000018 ; ---------------------------------------------------------------------------
seg000:00000018 mov eax, 17Eh ; 备份的NtTestAlert前5个字节
seg000:00000018 ; ---------------------------------------------------------------------------
seg000:0000001D dw 5Eh
seg000:0000001F dw 60h
seg000:00000021 dd 80025h
seg000:00000025 aCProgramFilesM: ; DATA XREF: sub_235+Cr
seg000:00000025 unicode 0, <C:\Program Files\XXXXX\DLP\Agent\fcagcbh32.dll>,0
。。。。
seg000:00000235 ; =============== S U B R O U T I N E =======================================
seg000:00000235
seg000:00000235 ; Attributes: bp-based frame
seg000:00000235
seg000:00000235 sub_235 proc near
seg000:00000235
seg000:00000235 var_54 = dword ptr -54h
seg000:00000235 var_44 = dword ptr -44h
seg000:00000235 var_34 = dword ptr -34h
seg000:00000235 var_30 = dword ptr -30h
seg000:00000235 var_2C = dword ptr -2Ch
seg000:00000235 var_28 = dword ptr -28h
seg000:00000235 var_24 = dword ptr -24h
seg000:00000235 var_20 = dword ptr -20h
seg000:00000235 var_1C = dword ptr -1Ch
seg000:00000235 var_18 = dword ptr -18h
seg000:00000235 var_14 = dword ptr -14h
seg000:00000235 var_10 = dword ptr -10h
seg000:00000235 var_C = dword ptr -0Ch
seg000:00000235 var_8 = dword ptr -8
seg000:00000235 var_4 = dword ptr -4
seg000:00000235
seg000:00000235 push ebp
seg000:00000236 mov ebp, esp
seg000:00000238 add esp, 0FFFFFFACh ; sub esp, 84
seg000:0000023B push ebx
seg000:0000023C push esi
seg000:0000023D push edi
seg000:0000023E mov [ebp+var_C], eax ; [ebp+var_C]<-ShellCodeBase
seg000:00000241 mov ecx, dword ptr fs:aCProgramFilesM+0Bh
seg000:00000248 mov [ebp+var_4], ecx ; [ebp+var_4]<-_PEB地址
seg000:0000024B mov [ebp+var_8], ebp
seg000:0000024E mov eax, [ebp+var_C]
seg000:00000251 mov eax, [eax+14h]
seg000:00000254 mov edx, [ebp+var_8]
seg000:00000257 add edx, 4
seg000:0000025A mov [edx], eax ; 修改该函数返回地址为pfnNtTestAlert
seg000:0000025C xor eax, eax
seg000:0000025E mov [ebp+var_28], eax
seg000:00000261 xor eax, eax
seg000:00000263 mov [ebp+var_2C], eax
seg000:00000266 mov eax, [ebp+var_4]
seg000:00000269 add eax, 0Ch ; Offset _PEB->Ldr
seg000:0000026C mov eax, [eax] ; eax指向_PEB_LDR_DATA
seg000:0000026E add eax, 14h ; eax 指向_PEB_LDR_DATA->InMemoryOrderModuleList
seg000:00000271 mov [ebp+var_18], eax
seg000:00000274 mov eax, [ebp+var_18]
seg000:00000277 mov esi, eax
seg000:00000279 lea edi, [ebp+var_54]
seg000:0000027C mov ecx, 9
seg000:00000281 rep movsd
seg000:00000283 jmp loc_48A
seg000:00000288 ; ---------------------------------------------------------------------------
seg000:00000288
seg000:00000288 loc_288: ; CODE XREF: sub_235+25Bj
seg000:00000288 mov eax, [ebp+var_54]
seg000:0000028B mov esi, eax
seg000:0000028D lea edi, [ebp+var_54]
seg000:00000290 mov ecx, 9
seg000:00000295 rep movsd
seg000:00000297 cmp [ebp+var_34], 0
seg000:0000029B jz loc_48A
seg000:000002A1 xor ebx, ebx
seg000:000002A3 jmp short loc_2A6 ; 从链表中查找ntdll.dll模块
seg000:000002A5 ; ---------------------------------------------------------------------------
seg000:000002A5
seg000:000002A5 loc_2A5: ; CODE XREF: sub_235+79j
seg000:000002A5 inc ebx
seg000:000002A6
seg000:000002A6 loc_2A6: ; CODE XREF: sub_235+6Ej
seg000:000002A6 mov eax, [ebp+var_34] ; 从链表中查找ntdll.dll模块
seg000:000002A9 cmp word ptr [eax+ebx*2], 0
seg000:000002AE jnz short loc_2A5
seg000:000002B0 mov eax, [ebp+var_34]
seg000:000002B3 lea eax, [eax+ebx*2-12h]
seg000:000002B7 cmp dword ptr [eax+4], 6C0064h ; "ld"
seg000:000002BE jnz loc_48A
seg000:000002C4 cmp dword ptr [eax], 74006Eh ; "tn"
seg000:000002CA jnz loc_48A
seg000:000002D0 mov eax, [ebp+var_34]
seg000:000002D3 lea eax, [eax+ebx*2-0Ah]
seg000:000002D7 cmp dword ptr [eax+4], 6C0064h ; "ld"
seg000:000002DE jnz loc_48A
seg000:000002E4 cmp dword ptr [eax], 2E006Ch ; ".l"
seg000:000002EA jnz loc_48A
seg000:000002F0 mov esi, [ebp+var_44]
seg000:000002F3 lea eax, [esi+3Ch]
seg000:000002F6 mov eax, [eax]
seg000:000002F8 add eax, esi
seg000:000002FA mov [ebp+var_1C], eax
seg000:000002FD mov eax, [ebp+var_1C]
seg000:00000300 mov eax, [eax+78h]
seg000:00000303 add eax, esi
seg000:00000305 mov edi, eax
seg000:00000307 mov eax, [edi+18h]
seg000:0000030A dec eax
seg000:0000030B test eax, eax
seg000:0000030D jl loc_496
seg000:00000313 inc eax
seg000:00000314 mov [ebp+var_30], eax
seg000:00000317 mov [ebp+var_20], 0
seg000:0000031E
seg000:0000031E loc_31E: ; CODE XREF: sub_235+24Dj
seg000:0000031E mov eax, [edi+20h] ; 查找函数"LdrLoadDll"
seg000:00000321 add eax, esi
seg000:00000323 mov edx, [ebp+var_20]
seg000:00000326 mov eax, [eax+edx*4]
seg000:00000329 add eax, esi
seg000:0000032B mov [ebp+var_24], eax
seg000:0000032E cmp [ebp+var_24], 0
seg000:00000332 jz loc_47C
seg000:00000338 mov eax, [ebp+var_24]
seg000:0000033B cmp dword ptr [eax+4], 'Ddao'
seg000:00000342 jnz short loc_360 ; 查找函数"NtProtectVirtualMemory"
seg000:00000344 cmp dword ptr [eax], 'LrdL'
seg000:0000034A jnz short loc_360 ; 查找函数"NtProtectVirtualMemory"
seg000:0000034C mov eax, [ebp+var_24]
seg000:0000034F add eax, 8
seg000:00000352 mov eax, [eax]
seg000:00000354 and eax, 0FFFFFFh
seg000:00000359 cmp eax, 'll'
seg000:0000035E jz short loc_3C3
seg000:00000360
seg000:00000360 loc_360: ; CODE XREF: sub_235+10Dj
seg000:00000360 ; sub_235+115j
seg000:00000360 mov eax, [ebp+var_24] ; 查找函数"NtProtectVirtualMemory"
seg000:00000363 cmp dword ptr [eax+4], 6365746Fh
seg000:0000036A jnz loc_47C
seg000:00000370 cmp dword ptr [eax], 7250744Eh
seg000:00000376 jnz loc_47C
seg000:0000037C mov eax, [ebp+var_24]
seg000:0000037F add eax, 8
seg000:00000382 cmp dword ptr [eax+4], 6C617574h
seg000:00000389 jnz loc_47C
seg000:0000038F cmp dword ptr [eax], 72695674h
seg000:00000395 jnz loc_47C
seg000:0000039B mov eax, [ebp+var_24]
seg000:0000039E add eax, 10h
seg000:000003A1 mov edx, [eax+4]
seg000:000003A4 mov eax, [eax]
seg000:000003A6 and edx, 0FFFFFFh
seg000:000003AC cmp edx, 7972h
seg000:000003B2 jnz loc_47C
seg000:000003B8 cmp eax, 6F6D654Dh
seg000:000003BD jnz loc_47C
seg000:000003C3
seg000:000003C3 loc_3C3: ; CODE XREF: sub_235+129j
seg000:000003C3 mov eax, [edi+24h]
seg000:000003C6 add eax, esi
seg000:000003C8 mov edx, [ebp+var_20]
seg000:000003CB movzx eax, word ptr [eax+edx*2]
seg000:000003CF mov [ebp+var_8], eax
seg000:000003D2 mov eax, [edi+1Ch]
seg000:000003D5 add eax, esi
seg000:000003D7 mov edx, [ebp+var_8]
seg000:000003DA mov eax, [eax+edx*4]
seg000:000003DD mov [ebp+var_8], eax
seg000:000003E0 mov eax, [ebp+var_24]
seg000:000003E3 cmp byte ptr [eax], 4Ch ; 'L'
seg000:000003E6 jnz short loc_3F2
seg000:000003E8 mov eax, [ebp+var_8]
seg000:000003EB add eax, esi
seg000:000003ED mov [ebp+var_2C], eax
seg000:000003F0 jmp short loc_3FA ; 修改函数NtTestAlert所在页面属性为PAGE_READWRITE_EXECUTE
seg000:000003F2 ; ---------------------------------------------------------------------------
seg000:000003F2
seg000:000003F2 loc_3F2: ; CODE XREF: sub_235+1B1j
seg000:000003F2 mov eax, [ebp+var_8]
seg000:000003F5 add eax, esi
seg000:000003F7 mov [ebp+var_28], eax
seg000:000003FA
seg000:000003FA loc_3FA: ; CODE XREF: sub_235+1BBj
seg000:000003FA cmp [ebp+var_2C], 0 ; 修改函数NtTestAlert所在页面属性为PAGE_READWRITE_EXECUTE
seg000:000003FE jz short loc_47C
seg000:00000400 cmp [ebp+var_28], 0
seg000:00000404 jz short loc_47C
seg000:00000406 mov eax, [ebp+var_C]
seg000:00000409 mov eax, [eax+14h]
seg000:0000040C mov [ebp+var_14], eax
seg000:0000040F mov [ebp+var_8], 5
seg000:00000416 lea eax, [ebp+var_10]
seg000:00000419 push eax
seg000:0000041A push 40h ; '@'
seg000:0000041C lea eax, [ebp+var_8]
seg000:0000041F push eax
seg000:00000420 lea eax, [ebp+var_14]
seg000:00000423 push eax
seg000:00000424 push 0FFFFFFFFh
seg000:00000426 call [ebp+var_28] ; pfnNtProtectVirutalMemory
seg000:00000429 mov eax, [ebp+var_C]
seg000:0000042C mov eax, [eax+14h] ; eax<-pfnNtTestAlert
seg000:0000042F mov edx, [ebp+var_C]
seg000:00000432 mov ecx, [edx+18h] ; ecx指向函数NtTestAlert备份的前4个字节
seg000:00000435 mov [eax], ecx
seg000:00000437 mov cl, [edx+1Ch]
seg000:0000043A mov [eax+4], cl ; 还原NtTestAlert前5个字节内容
seg000:0000043D mov [ebp+var_8], 5
seg000:00000444 lea eax, [ebp+var_10]
seg000:00000447 push eax
seg000:00000448 mov eax, [ebp+var_10]
seg000:0000044B push eax
seg000:0000044C lea eax, [ebp+var_8]
seg000:0000044F push eax
seg000:00000450 lea eax, [ebp+var_14]
seg000:00000453 push eax
seg000:00000454 push 0FFFFFFFFh
seg000:00000456 call [ebp+var_28] ; 还原NtTestAlert函数所在页面属性
seg000:00000459
seg000:00000459 loc_459: ; CODE XREF: sub_235+243j
seg000:00000459 lea eax, [ebp+var_8]
seg000:0000045C push eax
seg000:0000045D mov eax, [ebp+var_C]
seg000:00000460 add eax, 1Dh
seg000:00000463 push eax
seg000:00000464 push 0
seg000:00000466 push 0
seg000:00000468 call [ebp+var_2C] ; 调用LdrLoadDll函数装入Dll
seg000:0000046B mov eax, [ebp+var_C]
seg000:0000046E mov eax, [eax+10h]
seg000:00000471 mov [ebp+var_C], eax
seg000:00000474 cmp [ebp+var_C], 0
seg000:00000478 jnz short loc_459
seg000:0000047A jmp short loc_496
seg000:0000047C ; ---------------------------------------------------------------------------
seg000:0000047C
seg000:0000047C loc_47C: ; CODE XREF: sub_235+FDj
seg000:0000047C ; sub_235+135j ...
seg000:0000047C inc [ebp+var_20]
seg000:0000047F dec [ebp+var_30]
seg000:00000482 jnz loc_31E ; 查找函数"LdrLoadDll"
seg000:00000488 jmp short loc_496
seg000:0000048A ; ---------------------------------------------------------------------------
seg000:0000048A
seg000:0000048A loc_48A: ; CODE XREF: sub_235+4Ej
seg000:0000048A ; sub_235+66j ...
seg000:0000048A mov eax, [ebp+var_54]
seg000:0000048D cmp eax, [ebp+var_18]
seg000:00000490 jnz loc_288
seg000:00000496
seg000:00000496 loc_496: ; CODE XREF: sub_235+D8j
seg000:00000496 ; sub_235+245j ...
seg000:00000496 pop edi
seg000:00000497 pop esi
seg000:00000498 pop ebx
seg000:00000499 mov esp, ebp
seg000:0000049B pop ebp
seg000:0000049C retn
seg000:0000049C sub_235 endp
seg000:0000049C
seg000:0000049C ; ---------------------------------------------------------------------------
seg000:0000049D align 1000h
seg000:0000049D seg000 ends
seg000:0000049D
seg000:0000049D
seg000:0000049D end
[培训]《安卓高级研修班(网课)》月薪三万计划,掌
握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法