[原创]某公司DLP产品通过驱动注入DLL分析
最近在分析某公司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
