nothize
October 7th, 2009, 13:10
Code:
/--------------------\
| 0 - Introduction |
\--------------------/
This is a request for help of a crash analysis of xxxxx10b.ocx crashed within a browser. The crash dump is analyzed but with 2 mysteries unexplained.
There are 4 sections below:
1. Crash dump analysis
The crash dump of the browser was analyzed with windbg. This section includes the result of the !analyze -v command, the r(register) command and the page protection information. Comments are colored in blue.
2. IDA analysis
The binary of xxxxx10b.ocx is loaded into IDA for static analysis. This section contains the disassembly of the caller before the crash. The nProcessor variable was traced by cross reference and the purpose is found to be storing the number of processors.
3. Disassembly around crash point
Since the crash point != eax, the last function pointer to call, the disassembly starting from eax are analyzed to help finding the most reasnoable execution path.
4. Analysis evaluation
The result and analysis of the incident is presented in this section. The unknowns / questions are also written here.
/---------------------------------\
| 1 - Crash dump !analyze -v |
\---------------------------------/
EXCEPTION_RECORD: ffffffff -- (.exr ffffffffffffffff)
ExceptionAddress: 035db7c3
ExceptionCode: c0000096
ExceptionFlags: 00000000
NumberParameters: 0
BUGCHECK_STR: c0000096
DEFAULT_BUCKET_ID: APPLICATION_FAULT
PROCESS_NAME: browser.exe
ERROR_CODE: (NTSTATUS) 0xc0000096 - {
THREAD_ATTRIBUTES:
LAST_CONTROL_TRANSFER: from 045761a0 to 035db7c3
STACK_TEXT:
WARNING: Frame IP not in any known module. Following frames may be wrong.
0617e334 045761a0 00000001 18b83ef0 00000000 0x35db7c3
0790d444 00000000 00000003 00080813 00000000 Xxxxx10b+0x761a0
As seen from the stack, the return address is 45761a0, arg0 is 00000001. Matched push 0x1; call eax at .text:1007619C.
18b83ef0 matched push edi at .text:10076170.
FOLLOWUP_IP:
Xxxxx10b+761a0
045761a0 8b4f44 mov ecx,[edi+0x44]
SYMBOL_STACK_INDEX: 1
FOLLOWUP_NAME: MachineOwner
SYMBOL_NAME: Xxxxx10b+761a0
MODULE_NAME: Xxxxx10b
IMAGE_NAME: Xxxxx10b.ocx
DEBUG_FLR_IMAGE_TIMESTAMP: 4987a6c3
STACK_COMMAND: .ecxr ; kb
FAILURE_BUCKET_ID: c0000096_Xxxxx10b+761a0
BUCKET_ID: c0000096_Xxxxx10b+761a0
Followup: MachineOwner
---------
0:029> r
eax=035db7b0 ebx=00000000 ecx=00020002 edx=08740000 esi=00000002 edi=18b83ef0
eip=035db7c3 esp=0617e338 ebp=0790d444 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
035db7c3 ed in eax,dx
0:029> !vprot eax
BaseAddress: 03590000
AllocationBase: 03590000
AllocationProtect: 00000004 PAGE_READWRITE
RegionSize: 00068000
State: 00001000 MEM_COMMIT
Protect: 00000004 PAGE_READWRITE
Type: 00020000 MEM_PRIVATE
There is no EXECUTE access in this memory region.
0:029> !vprot 45761a0
BaseAddress: 04501000
AllocationBase: 04500000
AllocationProtect: 00000080 PAGE_EXECUTE_WRITECOPY
RegionSize: 002e9000
State: 00001000 MEM_COMMIT
Protect: 00000010 PAGE_EXECUTE
Type: 01000000 MEM_IMAGE
While the return address has EXECUTE access.
/---------------\
| 2 - IDA |
\---------------/
.text:10076170 sub_10076170 proc near ; CODE XREF: sub_10082F10+131j
.text:10076170 ; sub_10088C30+251p
.text:10076170 57 push edi ;
.text:10076171 8B F9 mov edi, ecx
.text:10076173 83 7F 44+ cmp dword ptr [edi+44h], 0
.text:10076177 74 3B jz short loc_100761B4
.text:10076179 56 push esi
.text:1007617A 33 F6 xor esi, esi
.text:1007617C 39 35 8C+ cmp nProcessor, esi
.text:10076182 7E 2F jle short loc_100761B3
.text:10076184
.text:10076184 loc_10076184: ; CODE XREF: sub_10076170+41j
.text:10076184 8B 47 44 mov eax, [edi+44h] ; edi+44 = 18b83f34 -> 1886bc78
.text:10076187 83 3C B0+ cmp dword ptr [eax+esi*4], 0
.text:1007618B 8D 04 B0 lea eax, [eax+esi*4] ; for esi=2, [eax+esi*4] -> 00020002
.text:1007618E 74 1A jz short loc_100761AA
.text:10076190 8B 00 mov eax, [eax]
.text:10076192 85 C0 test eax, eax
.text:10076194 74 0A jz short loc_100761A0
.text:10076196 8B 10 mov edx, [eax] ; edx = 08740000
.text:10076198 8B C8 mov ecx, eax ; ecx = 00020002
.text:1007619A 8B 02 mov eax, [edx] ; eax = 035db7b0
.text:1007619C 6A 01 push 1
.text:1007619E FF D0 call eax ; crash later at 035db7c3
.text:100761A0
.text:100761A0 loc_100761A0: ; CODE XREF: sub_10076170+24j
.text:100761A0 8B 4F 44 mov ecx, [edi+44h]
.text:100761A3 C7 04 B1+ mov dword ptr [ecx+esi*4], 0
.text:100761AA
.text:100761AA loc_100761AA: ; CODE XREF: sub_10076170+1Ej
.text:100761AA 46 inc esi
.text:100761AB 3B 35 8C+ cmp esi, nProcessor ; nProcessor is 2 in the crash dump.
.text:100761AB 40 37 10 ; cmp esi, 2
.text:100761AB ;
.text:100761B1 7C D1 jl short loc_10076184 ; Why would jl jmp when esi = 2?
/-------------------------------------\
| 3 - Disassembly on 035db7b0 |
\-------------------------------------/
Crash dump disassembly:
035db7b0 c00000 rol byte ptr [eax],0x0
035db7b3 0000 add [eax],al
035db7b5 0200 add al,[eax]
035db7b7 0000 add [eax],al
035db7b9 0100 add [eax],eax
035db7bb 0000 add [eax],al
035db7bd 0100 add [eax],eax
035db7bf 0128 add [eax],ebp
035db7c1 55 push ebp
035db7c2 e7ed out ed,eax
Reconstructed disassembly(Since the code here appear to be self-modifying):
035db7b0 0000 add [eax],al
035db7b2 0000 add [eax],al
035db7b4 0002 add [edx],al
035db7b6 0000 add [eax],al
035db7b8 0001 add [ecx],al
035db7ba 0000 add [eax],al
035db7bc 0001 add [ecx],al
035db7be 0001 add [ecx],al
035db7c0 2855e7 sub [ebp-0x19],dl
035db7c3 ed in eax,dx
/---------------------------\
| 4 - Analysis evaluation |
\---------------------------/
From the information available, the following points are guessed:
- The crash point was at 035db7c3.
- The caller was 0457619e by call eax.
- eax was 035db7b0.
- The machine code at 035db7b0 to 035db7c0 shows that the control flowed from 035db7b0 to 035db7c3. ((4 * 0xb0) & 0xff = c0 at 035db7b0)
- The register dump shows that the loop at loc_10076184 were executed before the crash.
However, there are 2 mysteries:
1. Why esi = 2 but it can still branch from 100761b1?
2. Why can 035db7b0 being executed when the protection info shows that there was no EXECUTE access?
Experiment shows that setting eip to memory location with the same characteristic as 035db7b0 will result in access violation.
Any comments or suggestions are welcome!