Experimental Use of 64-bit Dump of 32-bit .NET Process in WinDbg

A .NET dmp file is typically best captured as 32-bit for 32-bit process. On x64 system this could be using the 32-bit task manager (C:\windows\syswow64\taskmgr.exe), WinDbg (x86), or a tool like ProcDump (http://live.sysinternals.com/ProcDump.exe )

However what if a 32-bit .NET process has already been captured in 64-bit dmp file, and the issue is really hard to reproduce?

If you try to open with WinDbg x64 and try to load SOS you will get a failure:


wow64cpu!CpupSyscallStub+0x2:
00000000`76f21eb2 c3              ret
0:000> .loadby sos clr
The call to LoadLibrary(C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos) failed, Win32 error 0n193
    “%1 is not a valid Win32 application.”
Please check your debugger configuration and/or network access.

So we try to force load of x64 SOS:

0:000> .cordll -u -ve -I clr -lp c:\windows\microsoft.net\framework64\v4.0.30319
Automatically loaded SOS Extension
CLRDLL: Loaded DLL c:\windows\microsoft.net\framework64\v4.0.30319\mscordacwks.dll
CLR DLL status: Loaded DLL c:\windows\microsoft.net\framework64\v4.0.30319\mscordacwks.dll

However we can’t run any SOS commands successfully:

0:000> !threads
Failed to load data access DLL, 0x80004005
Verify that 1) you have a recent build of the debugger (6.2.14 or newer)
            2) the file mscordacwks.dll that matches your version of clr.dll is
                in the version directory or on the symbol path
            3) or, if you are debugging a dump file, verify that the file
                mscordacwks_<arch>_<arch>_<version>.dll is on your symbol path.
            4) you are debugging on supported cross platform architecture as
                the dump file. For example, an ARM dump file must be debugged
                on an X86 or an ARM machine; an AMD64 dump file must be
                debugged on an AMD64 machine.

You can also run the debugger command .cordll to control the debugger’s
load of mscordacwks.dll.  .cordll -ve -u -l will do a verbose reload.
If that succeeds, the SOS command should work on retry.

If you are debugging a minidump, you need to make sure that your executable
path is pointing to clr.dll as well.
0:000> .cordll -ve -u -l
CLRDLL: LoadLibrary(C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscordacwks.dll) failed, Win32 error 193
CLRDLL: Unable to find mscordacwks_AMD64_x86_4.6.42.00.dll by mscorwks search
CLRDLL: Unable to find ‘mscordacwks_AMD64_x86_4.6.42.00.dll’ on the path
CLRDLL: Unable to get version info for ‘c:\symbols\clr.dll\54EFEAF769a000\mscordacwks_AMD64_x86_4.6.42.00.dll’, Win32 error 0n87
Cannot Automatically load SOS
CLRDLL: ERROR: Unable to load DLL mscordacwks_AMD64_x86_4.6.42.00.dll, Win32 error 0n87
CLR DLL status: ERROR: Unable to load DLL mscordacwks_AMD64_x86_4.6.42.00.dll, Win32 error 0n87

Trying to use SosEX extension also fails:

0:000:x86> .load C:\debugging\sosex64.dll
This dump has no SOSEX heap index.
The heap index makes searching for references and roots much faster.
To create a heap index, run !bhi
0:000:x86> !bhi
The target is 32-bit. 32-bit managed targets must be debugged using a 32-bit debugger.
0:000:x86> !wow64exts.sw
Switched to Host mode
0:000> !bhi
CLRDLL: CLR DLL load disabled
Unable to initialize .NET data interface. Version 4.6.42.0 of mscordacwks.dll is required.
Locate and load the correct version of mscordacwks.dll. See documentation for the .cordll command.

So we try to open dmp file in WinDbg (x86) :

0:000> .loadby sos clr
0:000> !threads
SOS does not support the current target architecture.

0:000> .load wow64exts
0:000> !wow64exts.sw
Switched to Guest (WoW) mode
0:000:x86> !threads
SOS does not support the current target architecture.

0:000:x86> .load c:\support\sosex32.dll
This dump has no SOSEX heap index.
The heap index makes searching for references and roots much faster.
To create a heap index, run !bhi
0:000:x86> !bhi
Enumerating heap objects…Failed to load module 00000000012d3fbc. Error = 0x80131c49
Failed to load module 00000000012d3fbc. Error = 0x80131c49
Request for array class data for 0000000071635a78 failed. Error=0x80004001.
BuildHeapIndex failed. Error = 0x80004001.

0:000:x86> !wow64exts.sw
Switched to Host mode
0:000> !bhi
The target is 64-bit. 64-bit managed targets must be debugged using a 64-bit debugger.

What if we try removing the SOS architecture check, will it explode?

To do this I opened another instance of WinDbg (x86) and selected File –> Attach to a Process and selected our WinDbg (x86) process that had SOS extension loaded.

(225c.1f34): Break instruction exception – code 80000003 (first chance)
eax=feaab000 ebx=00000000 ecx=77771080 edx=10010044 esi=77771080 edi=77771080
eip=7773b270 esp=07c6f8b4 ebp=07c6f8e0 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!DbgBreakPoint:
7773b270 cc              int     3
0:002> lmvm sos
Browse full module list
start    end        module name
54890000 54950000   sos        (deferred)            
    Image path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos.dll
    Image name: sos.dll
    Browse all global symbols  functions  data
    Timestamp:        Fri Feb 27 14:50:08 2015 (54EFE970)
    CheckSum:         000B91DB
    ImageSize:        000C0000
    File version:     4.6.42.0
    Product version:  4.0.30319.0
    File flags:       8 (Mask 3F) Private
    File OS:          4 Unknown Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0409.04b0
    CompanyName:      Microsoft Corporation
    ProductName:      Microsoft® .NET Framework
    InternalName:     SOS.dll
    OriginalFilename: SOS.dll
    ProductVersion:   4.6.42.0
    FileVersion:      4.6.42.0 built by: NETFXREL1
    PrivateBuild:     DDBLD629A
    FileDescription:  Microsoft NTSD extension for .NET Runtime
    LegalCopyright:   © Microsoft Corporation.  All rights reserved.
    Comments:         Flavor=Retail
0:002> s -a 0x54890000 0x54950000 “SOS does not support the current target architecture”
54893224  53 4f 53 20 64 6f 65 73-20 6e 6f 74 20 73 75 70  SOS does not sup

Let’s try and find a reference to this address. We’ll convert it into Little Endian (reverse it) and search for those bytes 24 32 89 54

0:001> s -b 0x54890000 0x54950000 24 32 89 54
548af180  24 32 89 54 89 35 ac c0-91 54 e8 11 79 03 00 83  $2.T.5…T..y…

Now let’s disassemble that function:

0:001> uf 548af180

sos!ArchQuery:
548af140 55              push    ebp
548af141 8bec            mov     ebp,esp
548af143 51              push    ecx
548af144 a1fcc09154      mov     eax,dword ptr [sos!g_ExtControl (5491c0fc)]
548af149 8d55fc          lea     edx,[ebp-4]
548af14c 56              push    esi
548af14d 52              push    edx
548af14e 50              push    eax
548af14f 8b08            mov     ecx,dword ptr [eax]
548af151 33f6            xor     esi,esi
548af153 ff9190000000    call    dword ptr [ecx+90h]
548af159 8b45fc          mov     eax,dword ptr [ebp-4]
548af15c 3d4c010000      cmp     eax,14Ch
548af161 750a            jne     sos!ArchQuery+0x2d (548af16d)  Branch

sos!ArchQuery+0x23:
548af163 e888feffff      call    sos!X86Machine::GetInstance (548aeff0)
548af168 8bf0            mov     esi,eax
548af16a 8b45fc          mov     eax,dword ptr [ebp-4]

sos!ArchQuery+0x2d:
548af16d 3dc4010000      cmp     eax,1C4h
548af172 7507            jne     sos!ArchQuery+0x3b (548af17b)  Branch

sos!ArchQuery+0x34:
548af174 e8f7fdffff      call    sos!ARMMachine::GetInstance (548aef70)
548af179 8bf0            mov     esi,eax

sos!ArchQuery+0x3b:
548af17b 85f6            test    esi,esi
548af17d 751d            jne     sos!ArchQuery+0x5c (548af19cBranch <- Jumps if valid platform

sos!ArchQuery+0x3f:
548af17f 6824328954      push    offset sos!`string’ (54893224) <- ERROR MESSAGE
548af184 8935acc09154    mov     dword ptr [sos!g_targetMachine (5491c0ac)],esi
548af18a e811790300      call    sos!ExtErr (548e6aa0)
548af18f 83c404          add     esp,4
548af192 b805400080      mov     eax,80004005h
548af197 5e              pop     esi
548af198 8be5            mov     esp,ebp
548af19a 5d              pop     ebp
548af19b c3              ret

sos!ArchQuery+0x5c:
548af19c 8935acc09154    mov     dword ptr [sos!g_targetMachine (5491c0ac)],esi
548af1a2 33c0            xor     eax,eax
548af1a4 5e              pop     esi
548af1a5 8be5            mov     esp,ebp
548af1a7 5d              pop     ebp
548af1a8 c3              ret
0:001> u 54893224
sos!`string':
54893224 53              push    ebx
54893225 4f              dec     edi
54893226 53              push    ebx
54893227 20646f65        and     byte ptr [edi+ebp*2+65h],ah
5489322b 7320            jae     sos!`string’+0x29 (5489324d)
5489322d 6e              outs    dx,byte ptr [esi]
5489322e 6f              outs    dx,dword ptr [esi]
5489322f 7420            je      sos!`string’+0x2d (54893251)

We take the address of the conditional jmp we want to remove, and replace it with an unconditional jmp:

0:001> a 548af17d
548af17d
jmp sos!ArchQuery+0x5c
jmp sos!ArchQuery+0x5c
548af17f <Ctrl+C>

We can now see in decompilation the jmp is gone:

sos!ArchQuery+0x3b:
548af17b 85f6            test    esi,esi
548af17d eb1d            jmp     sos!ArchQuery+0x5c (548af19c)  Branch

We continue with ‘g’ and go back to our WinDbg that has the bad dmp file open…

Now we’re getting somewhere:

Pre Patch

0:000:x86> !threads
SOS does not support the current target architecture.

Post Patch

At least now we can run some SOS commands. Many commands work, or at least partially work. They may not behave 100% correctly, but at least some of the information seems to be correct in my initial investigation.


0:000:x86> !threads
ThreadCount:      2
UnstartedThread:  0
BackgroundThread: 1
PendingThread:    0
DeadThread:       0
Hosted Runtime:   no
                                                                         Lock 
       ID OSID ThreadOBJ    State GC Mode     GC Alloc Context  Domain   Count Apt Exception
   0    1 1ad4 0112ac20     a6028 Preemptive  0324F8A8:00000000 01124b98 1     STA System.Runtime.InteropServices.SEHException 0324f644
   2    2 1e04 01138b70     2b228 Preemptive  00000000:00000000 01124b98 0     MTA (Finalizer)

0:000:x86> !pe
Exception object: 0324f644
Exception type:   System.Runtime.InteropServices.SEHException
Message:          External component has thrown an exception.
InnerException:   <none>
StackTrace (generated):
c0000005 Exception in C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll.pe debugger extension.
      PC: 548c5f3d  VA: 00000000  R/W: 0  Parameter: 00000000

Stack based commands (!dumpstack \ !clrstack \!eestack ) however will thrown an exception like this in the debugger.

(225c.21e0): Access violation – code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=0635d844 ecx=00000000 edx=00000000 esi=778d919c edi=00fbb644
eip=548a87b3 esp=0635d26c ebp=0635d7f4 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206
sos!DumpStackWorker+0x63:
548a87b3 8b01            mov     eax,dword ptr [ecx]  ds:002b:00000000=????????

And result in error displayed in WinDbg

0:000:x86> !DumpStack
OS Thread Id: 0x1ad4 (0)
TEB information is not available so a stack size of 0xFFFF is assumed
Current frame: ntdll_77870000!NtWaitForSingleObject+0xc
c0000005 Exception in C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll.DumpStack debugger extension.
      PC: 548a87b3  VA: 00000000  R/W: 0  Parameter: 00000000

Posted in .NET, 64-bit, Patching, WinDbg | Tagged | Leave a comment

Patching a Null Pointer Access Violation

An application was crashing about 5x a time a day so crash dumps were enabled via registry https://msdn.microsoft.com/en-us/library/windows/desktop/bb787181(v=vs.85).aspx

Looking at the dmp files the program always crashed at same point in the program.

This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
(51c.1160): Access violation – code c0000005 (first/second chance not available)
ntdll!NtWaitForMultipleObjects+0xa:
00007ff9`b879ed4a c3              ret
0:007> .ecxr
rax=0000000000000000 rbx=000000412a47e678 rcx=0000000000000010
rdx=000000412605e6c0 rsi=000000412a47d798 rdi=0000004123d9a040
rip=00007ff994a0a260 rsp=000000412605ea70 rbp=000000412a46e350
r8=00000041238b3820  r9=00000041280b7b10 r10=000000412380f430
r11=000000412605e230 r12=0000000000000004 r13=00007ff994a370f0
r14=00007ff9b21b1c80 r15=0000000000000000
iopl=0         nv up ei ng nz na pe cy
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010283
Updater!GetSettingsCollection+0x760:
00007ff9`94a0a260 443920         
cmp     dword ptr [rax],r12d ds:00000000`00000000=????????

While I waited for patch from vendor, I wanted to experiment patching the crash on my own. For patching I’ve used IDA Pro.

To easily find the code in IDA pro I first dumped the crash location in bytes:

0:007> db Updater!GetSettingsCollection+0x760
00007ff9`94a0a260  44 39 20 74 0c 83 38 06-75 0c 83 f9 40 74 07 eb  D9 t..8.u…@t..
00007ff9`94a0a270  aa 41 3b cc eb f7 48 8b-5c 24 40 48 8b 03 4c 8b  .A;…H.\$@H..L.
00007ff9`94a0a280  70 40 49 8b ce ff 15 9d-63 02 00 48 8d 54 24 58  p@I…..c..H.T$X
00007ff9`94a0a290  48 8b cb 41 ff d6 89 44-24 30 85 c0 0f 89 85 00  H..A…D$0……
00007ff9`94a0a2a0  00 00 e8 6d e6 00 00 83-38 02 0f 86 6b ff ff ff  …m….8…k…
00007ff9`94a0a2b0  c7 44 24 50 4c 0a 00 00-4c 89 ac 24 00 01 00 00  .D$PL…L..$….
00007ff9`94a0a2c0  48 c7 84 24 08 01 00 00-44 00 00 00 48 8d 4c 24  H..$….D…H.L$
00007ff9`94a0a2d0  50 48 89 8c 24 10 01 00-00 48 c7 84 24 18 01 00  PH..$….H..$…

I then loaded the faulting module, updater.dll, into IDA and searched for the first 8 bytes by clicking Search –> Find Sequence of Bytes. I also enabled Find all occurrences just in case this byte sequence re-occurred

image

With only one result, we found what we are looking for:

image

To find a place to insert my patch code, I went to end of the .text segment where we found alignment bytes

align 100h

To insert patch code we selected the align statement and changed it to code (‘C’ keyboard shortcut, or Edit –> Code )

So now we had something like this

db 0
db 0
db 0
etc

The patching code I wanted to insert would check if rax = 0 , if so jump to the location where [rax] was no longer used.

Something like

cmp rax,0
jz <Skip use of [rax]>
jmp <return to code using [rax]>

IDA’s Hex-Rays doesn’t support assembling x64 code, so I couldn’t use “assemble” to generate the byte code for the cmp instruction.

If I don’t know the byte code, I just did a quick search for similar instruction, and used the bytes from it – by searching for cmp rax, I found the bytes I needed

For the jump instructions I found jz near ptr loc_address works fine. However IDA will only assemble this if there is already a jump to that location, otherwise it will fail “Invalid Operand”

To manually calculate the jump, we take the subtract source & destination addresses:

18002FF31 (Source Address) – 18000A265 (Destination Address) = 25CCC + 5 (length of our jmp instruction) = 25CD1. Because we are jumping “backwards” make negative = FF FD A3 2F

I just used the Windows calculator in “hex mode” To get the negative hex number calculated 0 minus 25CD1.

Convert to Little Endian (Reverse Bytes) = 2F A3 FD FF

 

E9 is the op code for the relative jmp we need, so based on this calculation our jmp instruction is

E9 2F A3 FD FF

We insert these using IDA’s Edit –> Patch Program –> Change Bytes

Original Code

.text:000000018000A251 loc_18000A251:      
.text:000000018000A251                 mov     rax, [rsp+388h+var_2F8]
.text:000000018000A259                 mov     rax, [rax+108h]
.text:000000018000A260                 cmp     [rax], r12d <—Crash
.text:000000018000A263                 jz      short loc_18000A271
.text:000000018000A265                 cmp     dword ptr [rax], 6
.text:000000018000A268                 jnz     short loc_18000A276
.text:000000018000A26A                 cmp     ecx, 40h
.text:000000018000A26D
.text:000000018000A26D loc_18000A26D:  
.text:000000018000A26D                 jz      short loc_18000A276
.text:000000018000A26F                 jmp     short loc_18000A21B

Jump to Patched Code

000000018000A251 loc_18000A251:     
.text:000000018000A251                 mov     rax, [rsp+388h+var_2F8]
.text:000000018000A259                 mov     rax, [rax+108h]
.text:000000018000A260                 jmp     patched_code
.text:000000018000A265                 nop     ; because we couldn’t fit some
.text:000000018000A266                 nop     ; instruction here
.text:000000018000A267                 nop
.text:000000018000A268
.text:000000018000A268 loc_18000A268: ;
.text:000000018000A268                 jnz     short loc_18000A276
.text:000000018000A26A
.text:000000018000A26A loc_18000A26A:
.text:000000018000A26A                 cmp     ecx, 40h
.text:000000018000A26D
.text:000000018000A26D loc_18000A26D: 
.text:000000018000A26D                 jz      short loc_18000A276
.text:000000018000A26F                 jmp     short loc_18000A21B
.text:000000018000A271

.text:000000018000A271 loc_18000A271:         
.text:000000018000A271                 cmp     ecx, r12d
.text:000000018000A274                 jmp     short loc_18000A26D

The Patch:

.text:000000018002FF1F patched_code:                           ; CODE XREF: sub_180009B00+760j
.text:000000018002FF1F                 cmp     rax, 0
.text:000000018002FF23                 jz      loc_18000A21B ; If RAX=0 skip [RAX] code
.text:000000018002FF29                 cmp     [rax], r12d ; RAX!=0 continue on
.text:000000018002FF2C                 jz      loc_18000A271
.text:000000018002FF32                 cmp     dword ptr [rax], 6
.text:000000018002FF35                 jmp     loc_18000A268 ; continues normal execution of program

Once we were ready to test the changes we applied them by selecting Edit –> Patch Program –> Apply Patches to Input File

I always ensure I have a backup of original file, as it is quite easy to break something.

imagew

This patch did happen to resolve this crash. However doing this type of patch will frequently lead to other types of crash or bugs, and so can be a very time consuming process.

However it is important to remember, lost source code or bad vendor support, does not mean bugs can’t be fixed…

Posted in IDA, Patching, WinDbg | Tagged | Leave a comment

PowerShell Script to Remove Macro Password on Office 2003/2007/2010/2013 Documents

Usage:

.\Unlock-OfficeMacro.ps1 <input filename> <output filename>

Supports .doc, .docm, .xlsm, .ppt, etc. Please read description in script before using.

Download script here:

http://1drv.ms/1DdzLGG

Screenshot:

image

The script:

<# .SYNOPSIS Unlocks Office Macro Password Protection. .DESCRIPTION Unlocks Word/Excel/PowerPoint/etc 2003-2013 format files password protections. To access macros in Shared Excel Workbooks click Review -> Share Workbook and untick 'Allow changes by more than one user' An unlocked document will throw error --------------------------- Microsoft Visual Basic for Applications --------------------------- The project file 'C:\support\somefile.docm' contains invalid key 'DPx'.--Continue Loading Project? --------------------------- Yes No Help --------------------------- Click 'Yes' to continue, macro code will be accessible. To remove this warning, set a password on the macro, then remove it, then resave document. Common issues: - This is relying on Shell for ZIP/UNZIP if working on Office 2007+ format files This method is not very robust and will not be surprised if it breaks. If you get pop-up errors can't read file/etc then increase delay in line Start-Sleep -Seconds 3 - This script does not have huge amount of error checking. .EXAMPLE Unlock-OfficeMacro ProtectedWord.doc UnprotectedWord.doc .EXAMPLE Unlock-OfficeMacro C:\support\ProtectedWord.docm UnprotectedWord.docm .EXAMPLE Unlock-OfficeMacro -InputFile C:\support\ProtectedExcel.xlsm -OutputFile UnProtected.xlsm .PARAMETER InputFile The password protected office document. .PARAMETER OutputFile The output file with password protection removed. Should have same extension as inputfile. .NOTES By Malcolm McCaffery http://chentiangemalc.wordpress.com #> [CmdletBinding()] Param( [Parameter(Mandatory=$True,Position=1)] [string]$InputFile, [Parameter(Mandatory=$True,Position=2)] [string]$OutputFile ) # Binary "IndexOf" # too lazy (or busy…) to write this code in PowerShell, couldn’t find any good PowerShell example # And this is fast. From http://stackoverflow.com/users/649008/foubar # at http://stackoverflow.com/questions/283456/byte-array-pattern-search $compilerParameters = New-Object System.CodeDom.Compiler.CompilerParameters $compilerParameters.CompilerOptions="/unsafe" Add-Type -PassThru -CompilerParameters $compilerParameters -TypeDefinition @" using System; using System.Collections.Generic; public static class FastByte { public static unsafe long IndexOf(byte[] Haystack, byte[] Needle) { fixed (byte* H = Haystack) fixed (byte* N = Needle) { long i = 0; for (byte* hNext = H, hEnd = H + Haystack.LongLength; hNext < hEnd; i++, hNext++) { bool Found = true; for (byte* hInc = hNext, nInc = N, nEnd = N + Needle.LongLength; Found && nInc < nEnd; Found = *nInc == *hInc, nInc++, hInc++); if (Found) return i; } return -1; } } } "@ # check if file locked Function Test-FileLocked { param( [string]$Filename) $HRFileLocked = 0x80070020; $HRPortionOfFileLocked = 0x80070021; "Test $Filename is locked" try { $fs = [System.IO.File]::Open($filename, [System.IO.FileMode]::OpenOrCreate, [System.IO.FileAccess]::ReadWrite, [System.IO.Fileshare]::Write) $fs.Close() # file is not locked return $false } catch [System.IO.IOException] { "Error accessing $filename : $_" $errorCode = [System.Runtime.InteropServices.Marshal]::GetHRForException ($_.Exception) if ($errorCode -eq $HRFileLocked -or $errorCode -eq $HRPortionOfFileLocked) { # file is locked! return $true } else { # failures to open file, besides file is locked throw } } } # wait for file to become unlocked Function Wait-File { param( [string]$FileName, [System.TimeSpan]$Timeout=(New-TimeSpan -Seconds 60)) $StopWatch = [Diagnostics.StopWatch]::StartNew() while ($StopWatch.Elapsed -lt $Timeout) { if ((Test-FileLocked -FileName $FileName) -eq $true) { "$FileName is locked, retrying" } else { "$FileName is NOT locked" return } Start-Sleep -Milliseconds 500 } } Function Send-ZipFile { param( [string]$zipFilename, [string]$filename) $zipHeader=[char]80 + [char]75 + [char]5 + [char]6 + [char]0 + [char]0 + [char]0 + [char]0 + [char]0 + [char]0 + [char]0 + [char]0 + [char]0 + [char]0 + [char]0 + [char]0 + [char]0 + [char]0 + [char]0 + [char]0 + [char]0 + [char]0 # Check to see if the Zip file exists, if not create a blank one If ( (Test-Path $zipfilename) -eq $FALSE ) { Add-Content $zipfilename -value $zipHeader } # Create an instance to Windows Explorer's Shell comObject $ExplorerShell=New-Object -ComObject Shell.Application # Send whatever file / Folder is specified in $filename to the Zipped folder $zipfilename $SendToZip=$ExplorerShell.Namespace($zipFilename.tostring()).CopyHere ($filename.ToString(),0) # sleep long enough for "Copy here to at least start..." # this is a bit ugly but necessary if relying on shell # to put multiple files in the ZIP file Start-Sleep -Seconds 3 # wait for any writing to be completed on ZIP file Wait-File $ZipFilename } Function Expand-ZIPFile { Param( [String]$ZipFilename, [String]$DestinationPath) $shell = New-Object -ComObject Shell.Application $zip = $shell.NameSpace($ZipFileName) "Expand to $destination" $shell.Namespace($DestinationPath).CopyHere($zip.Items()) } $O2k7Format = $false # We’ll work on the copy—just in case we mess up the original Copy-Item $InputFile $OutputFile # Load our target file all at once # Not scalable … &c but works to test the concept Write-Host "Loading $OutputFile" $data=Get-Content -Encoding Byte $OutputFile $tempFolder="" # check if we are using Office 2007 or later file format # by looking for PK header (ZIP file)... if ($data[0] -eq 80 -and $data[1] -eq 75) { $O2k7Format = $true "Office 2007+ format, unzipping contents" # yes ... must unzip file first $tempFolder = [System.IO.Path]::Combine( [System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName()) # Rename output file to ZIP so we can use Shell 'unzip' $ZipFileName = $OutputFile + ".zip" Move-Item -Path $OutputFile -Destination $ZipFileName -Force New-Item -ItemType Directory -Path $tempFolder "Expanding files to $tempFolder" Expand-ZIPFile -ZipFileName $ZipFileName -DestinationPath $tempFolder # we don't need the ZIP file anymore, delete it Remove-Item $ZipFileName # get vbaProject.bin filename $vbaFileName = (Get-ChildItem -Path $tempFolder -Filter vbaProject.bin -Recurse) [0].FullName # use vbaProject.bin as our data stream $data=Get-Content -Encoding Byte $vbaFileName } Write-Host "Searching file contents" # The string we need to replace ( DPB= ) [Byte[]] $searchBytes = 0x44,0x50,0x42,0x3D,0x22 # This is the string we will use to break the macro protection ( DPx= ) [Byte[]] $replaceBytes = 0x44,0x50,0x78,0x3D,0x22 $index=[FastByte]::IndexOf($data,$searchBytes) Write-Host "Key found at $index" # update file if ($o2k7format) { [System.IO.Stream]$stream = [System.IO.File]::Open($vbaFileName, [System.IO.FileMode]::Open) } else { [System.IO.Stream]$stream = [System.IO.File]::Open($OutputFile, [System.IO.FileMode]::Open) } # write our replacement key $stream.Position=$index $stream.Write($replaceBytes,0,$replaceBytes.Length) $stream.Dispose() # if office 2007+ format, we need to rezip contents if ($o2k7format) { "Building ZIP file at $($OutputFile).zip" # delete ZIP if it already exists if (Test-Path $ZipFilename) { Remove-Item $ZipFilename } # rebuild Office "ZIP" file ForEach ($file in Get-ChildItem $tempFolder) { "Adding $($file.FullName) to $ZipFilename" Send-ZipFile -ZipFileName $ZipFilename -filename $file.FullName } "Moving $ZipFilename to $OutputFile" Wait-File $ZipFilename Move-Item -Path $ZipFilename -Destination $OutputFile -Force Remove-Item $tempFolder -Recurse } Write-Host "Update Complete! Output file: $OutputFile"

Posted in Hacking, PowerShell | Tagged | Leave a comment

Summarize A Folder of Event Logs with PowerShell

Sometimes you want to get a rapid summary of errors/warnings in the multitude of Windows event logs on a system. Point this to a folder of event logs to get a summary

https://onedrive.live.com/redir?resid=E1A3C870740A073D!22863&authkey=!AOS4jOVgoFYI2JE&ithint=file%2czip

<# .SYNOPSIS Provides a summary of event log errors .DESCRIPTION When pointed to a folder of Windows Event Logs (.evtx files) Will provide a summary of all critical/warning/error events, sorted by most frequent to least frequent In format <Event log filename> - <Event log message> .EXAMPLE Get-EventSummary -Path C:\windows\system32\winevt .EXAMPLE Get-EventSummary -Path C:\eventlogs -Recurse .EXAMPLE Get-EventSummary -Path c:\eventlogs | Out-GridView .EXAMPLE Get-EventSummary -Path C:\eventlogs | Out-Csv C:\support\out.csv .PARAMETER Path Path containing the Windows event log files (.EVTX format) .PARAMETER Recurse If specified subfolders will also be searched for .EVTX files. .LINK http://chentiangemalc.wordpress.com #> [CmdletBinding()] Param( [Parameter(Mandatory=$true)] [string]$Path, [switch]$Recurse ) $CriticalWarningErrorFilter = @' <QueryList> <Query Id="0"> <Select>*[System[(Level=1 or Level=2 or Level=3)]]</Select> </Query> </QueryList> '@ $eventCount=@{} if ($recurse) { $files = Get-ChildItem -Path $path -Filter "*.evtx" -Recurse } else { $files = Get-ChildItem -Path $path -Filter "*.evtx" } ForEach ($file in $files) { Write-Host "Searching $file for Warnings/Errors" # erroraction = ignore, so when no events found matching filter an error is not thrown $events = Get-WinEvent -Path $file.FullName -FilterXPath $CriticalWarningErrorFilter -ErrorAction Ignore ForEach ($event in $events) { if ($event.Message -ne $null) { $eventCount["$file - $($event.Message)"]++ } } } return ($eventCount.GetEnumerator() | Sort-Object Value -Descending)

Posted in PowerShell | Tagged | Leave a comment

Case of the Visual Basic Environment Could Not Be Initialized

Launching Word we got the following error:

image

Clicking Show Help we get some explanations of potential causes:

This error is usually caused by insufficient memory or low disk space. It also occurs when the default Word template (normal.dotm) is corrupt, when the VBE7.DLL file is the wrong version, or when permissions to the TEMP folder on a server share do not allow access to the folder by the user.
Low memory or disk space can be solved by either closing unused applications, removing unused programs or files from your hard drive, or by adding RAM or a larger hard drive. In some cases, a memory leak might have occurred and is exhausting RAM without your knowledge. If you suspect that a memory leak is the problem, shutdown Word and VBA and restart the computer.
Rename the normal.dotm file and then restart Microsoft Word. When you exit Word, Word will build a new normal.dotm file. If you have a backup of normal.dotm, you can replace the defective file by using the backup copy instead of having Word repair the file.
If the VBE7.DLL is not the correct version, replace it.
If your network permissions are insufficient for access to a TEMP folder on a server share, contact the administrator and determine whether the permissions can be changed. If they cannot, redirect VB to use a local TEMP folder.

Machine was not low on disk space, there was no problem accessing temp folder. Repairing office, removing normal.dotm file did not fix the issue.
 

Taking a trace with Rohitab API Monitor (https://chentiangemalc.wordpress.com/category/api-monitor/) I had the following APIs monitored:

  • Component Object Model (COM)
  • Data Access and Storage
  • System Services –> Windows System Information –> Registry
  • Visual C++ Runtime Library –> String Manipulation
  • Windows Application UI Development

From the trace we can search for the error message:

#    Time of Day    Thread    Module    API    Return Value    Error    Duration
256844    10:22:25.620 AM    1    mso.dll    wcsncpy_s ( 0x078bff48, 56, “The Visual Basic environment could not be initialized.”, -1 )    0        0.0000000

Now we can work backwards in log to identify what triggered the error message…

The first errors we came across are registry access errors:

#    Time of Day    Thread    Module    API    Return Value    Error    Duration
83242    5:59:37.126 AM    1    mso.dll    RegOpenKeyExW ( HKEY_LOCAL_MACHINE, “System\CurrentControlSet\Services\EventLog\OAlerts\Microsoft Office 15 Alerts”, 0, KEY_READ | KEY_CREATE_SUB_KEY | KEY_SET_VALUE, 0x0084884c )    ERROR_ACCESS_DENIED    5 = Access is denied.     0.0000713

However I don’t suspect these as we can see later another attempt was made to access key which succeeded:

#    Time of Day    Thread    Module    API    Return Value    Error    Duration
83243    5:59:37.126 AM    1    mso.dll    RegOpenKeyExW ( HKEY_LOCAL_MACHINE, “System\CurrentControlSet\Services\EventLog\OAlerts\Microsoft Office 15 Alerts”, 0, KEY_READ, 0x0084884c )    ERROR_SUCCESS        0.0000213

We then run into this event, which is more interesting:

#    Time of Day    Thread    Module    API    Return Value    Error    Duration
82554    5:59:37.076 AM    1    wwlib.dll    LoadRegTypeLib ( {00020905-0000-0000-c000-000000000046}, 8, 6, 1033, 0x651b2128 )    TYPE_E_LIBNOTREGISTERED    0x8002801d = Library not registered.     0.0001610

The preceding event relates to Visual Basic runtime:

#    Time of Day    Thread    Module    API    Return Value    Error    Duration
82551    5:59:37.076 AM    1    mso.dll    GetFileVersionInfoW ( “C:\Program Files (x86)\Common Files\Microsoft Shared\VBA\VBA7.1\VBE7.DLL”, 0, 2420, 0x08b8aa60 )    TRUE        0.0002327

Looking back further we find event

#    Time of Day    Thread    Module    API    Return Value    Error    Duration
78633    5:59:36.727 AM    1    wwlib.dll    RegisterTypeLib ( 0x089e8848, “C:\Program Files (x86)\Microsoft Office\Office15\MSWORD.OLB”, NULL )    TYPE_E_REGISTRYACCESS    0x8002801c = Error accessing the OLE registry.     0.0004030

The most common issue relating to accessing OLE registry would be lack of permissions. So I run Word as a local Administrator account.

This resulted in the following registry keys and values being added. After this Word was working fine.

Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\TypeLib\{00020905-0000-0000-C000-000000000046}] [HKEY_CLASSES_ROOT\TypeLib\{00020905-0000-0000-C000-000000000046}\8.6] @="Microsoft Word 15.0 Object Library" [HKEY_CLASSES_ROOT\TypeLib\{00020905-0000-0000-C000-000000000046}\8.6\0] [HKEY_CLASSES_ROOT\TypeLib\{00020905-0000-0000-C000-000000000046}\8.6\0\win32] @="C:\\Program Files (x86)\\Microsoft Office\\Office15\\MSWORD.OLB" [HKEY_CLASSES_ROOT\TypeLib\{00020905-0000-0000-C000-000000000046}\8.6\FLAGS] @="0" [HKEY_CLASSES_ROOT\TypeLib\{00020905-0000-0000-C000-000000000046}\8.6\HELPDIR] @="C:\\Program Files (x86)\\Microsoft Office\\Office15"

This type of problem could also have been identified with SysInternals ProcMon – but in this case there would be a much larger amount of “false positives” to sort through. In this scenario being able to drill down to event where error message was generated assisted finding root cause much more quickly.

Posted in API Monitor, Office | Tagged | Leave a comment

Unity Freeze At Logon in Ubuntu 14.04 LTS on Parallels

Running Ubuntu 14.04 after installing some updates it was no longer possible to get access to desktop. After logging in the desktop froze. Ctrl+Alt+T failed to bring up a Terminal Window in Unity, although this did work in Gnome Classic desktop. (although this desktop also failed to start)

image

Hit Ctrl+ALT F2 to get TTY console, logged in and ran

 

unity --advanced-debug

We can see error message /usr/bin/compwiz (core) – Error: Plugin ‘opengl’ not loaded

image

For this issue I re-installed the Parallels Drivers. To do so in Parallels I selected Virtual Machine –> Reinstall Parallels Tools

Then from console ran the following commands:

mkdir -p /mnt/cdrom sudo mount -t iso9660 -o ro /dev/cdrom /mnt/cdrom cd /mnt/cdrom sudo ./install

image

Then followed prompts to reinstall Parallels drivers…

image

After a reboot desktop now worked correctly…

Posted in Linux | Leave a comment

Case of the Word Scroll Hangs in Citrix

A simple one page document was causing Word to freeze on opening, and if it ever did open, attempting to use scroll bar caused some parts of a background image to appear intermittently.

3 dump files were collected using Task Manger. We see the following stacks. Example 2 & 3 were from same instance of the process.

Example #1

Process Uptime: 0 days 0:00:52.000

0:000:x86> !runaway
User Mode Time
  Thread       Time
   0:1ab4      0 days 0:00:44.468
   6:1ae4      0 days 0:00:00.015
  13:19fc      0 days 0:00:00.000
  12:2d0       0 days 0:00:00.000
  11:2510      0 days 0:00:00.000
  10:1fdc      0 days 0:00:00.000
   9:192c      0 days 0:00:00.000
   8:1220      0 days 0:00:00.000
   7:1e80      0 days 0:00:00.000
   5:2590      0 days 0:00:00.000
   4:15d8      0 days 0:00:00.000
   3:2448      0 days 0:00:00.000
   2:31c       0 days 0:00:00.000
   1:2418      0 days 0:00:00.000
0:000:x86> k
ChildEBP RetAddr 
001f546c 063f41dc GdiPlus!FLOOR+0x9
001f5478 063f41f6 GdiPlus!FPUStateSaver::Round+0x1d
001f5484 064dc28c GdiPlus!GpRound+0x11
001f54b4 064dcc34 GdiPlus!GpRecolorObject::TransformColor5x5+0x199
001f54c8 064dd03e GdiPlus!GpRecolorObject::ComputeColorTwist+0x91
001f54ec 06421894 GdiPlus!GpRecolorObject::ColorAdjust+0xfa
001f54fc 064e12e1 GdiPlus!GpRecolor::ColorAdjust+0x1e
001f5510 064e0d81 GdiPlus!GpRecolorOp::Run+0x18
001f5534 064ebe7d GdiPlus!GpBitmapOps::ReleasePixelDataBuffer+0x8a
001f55ec 064dd31e GdiPlus!GpWicDecoder::Decode+0x169
001f5600 064dda0f GdiPlus!GpDecodedImage::InternalPushIntoSink+0x2d
001f5618 064de571 GdiPlus!GpDecodedImage::PushIntoSink+0x3c
001f568c 06434fc6 GdiPlus!GpMemoryBitmap::InitImageBitmap+0x15f
001f56e0 06436c63 GdiPlus!CopyOnWriteBitmap::PipeLockBitsFromDecoder+0xa5
001f57bc 06436e69 GdiPlus!CopyOnWriteBitmap::PipeLockBits+0x56b
001f57d4 06441df8 GdiPlus!GpBitmap::PipeLockBits+0x50
001f5c68 06444718 GdiPlus!GpGraphics::DrvDrawImage+0x1eff
001f5d60 0644487d GdiPlus!GpGraphics::DrawImage+0x386
001f5dc4 0640e8da GdiPlus!GpGraphics::DrawImage+0x66
001f5e38 64d1f230 GdiPlus!GdipDrawImagePointsRect+0x1e5
WARNING: Stack unwind information not available. Following frames may be wrong.
001f5ea8 64d1f58b MSO!Ordinal1458+0x20b
001f619c 64d1ef43 MSO!Ordinal1458+0x566
001f61f8 64d1ee85 MSO!Ordinal8926+0x115
001f6248 64d1bcbf MSO!Ordinal8926+0x57
001f69c4 64d1e666 MSO!Ordinal6882+0x6a3
001f6a00 64d1e5b8 MSO!Ordinal3379+0x214
001f6c4c 64d196fc MSO!Ordinal3379+0x166
001f6c74 64d1eeb6 MSO!Ordinal1075+0x2a5d
001f6c98 64d1968e MSO!Ordinal8926+0x88
001f6ca8 64d194ff MSO!Ordinal1075+0x29ef
001f79a4 64d19363 MSO!Ordinal1075+0x2860
001f79cc 64d171e8 MSO!Ordinal1075+0x26c4
001f7ad8 64cfb39b MSO!Ordinal1075+0x549
001f7b44 313ce150 MSO!Ordinal423+0x155
001f7c3c 312351a0 WWLIB!DllGetLCID+0x1b20da
001f7c80 31235169 WWLIB!DllGetLCID+0x1912a
001f7fb8 310cfdee WWLIB!DllGetLCID+0x190f3
001f80a8 310c50b4 WWLIB!GetAllocCounters+0xa9996
001f80d8 310e980e WWLIB!GetAllocCounters+0x9ec5c
001f8130 3108050c WWLIB!GetAllocCounters+0xc33b6
001f81b0 310247b5 WWLIB!GetAllocCounters+0x5a0b4
001f81f0 766462fa WWLIB!DllGetClassObject+0xf161
001f821c 76647316 user32!InternalCallWinProc+0x23
001f8294 76646de8 user32!UserCallWinProcCheckWow+0xd8
001f82f0 76646e44 user32!DispatchClientMessage+0xe0
001f832c 7753010a user32!__fnDWORD+0x2b
001f8374 310794a3 ntdll_77520000!KiUserCallbackDispatcher+0x2e
001f8394 3107935a WWLIB!GetAllocCounters+0x5304b
001f83d8 3107f72b WWLIB!GetAllocCounters+0x52f02
001f83e4 3107f63e WWLIB!GetAllocCounters+0x592d3
001f8410 649e18c6 WWLIB!GetAllocCounters+0x591e6
001f843c 649e1682 MSO!Ordinal10331+0x399
001f844c 649e161d MSO!Ordinal10331+0x155
001f8460 31078dd8 MSO!Ordinal10331+0xf0
001f84b8 310252b7 WWLIB!GetAllocCounters+0x52980
001faa0c 310247b5 WWLIB!DllGetClassObject+0xfc63
001faa4c 766462fa WWLIB!DllGetClassObject+0xf161
001faa78 76646d3a user32!InternalCallWinProc+0x23
001faaf0 76650d27 user32!UserCallWinProcCheckWow+0x109
001fab28 76650d4d user32!CallWindowProcAorW+0xab
001fab48 70ebf443 user32!CallWindowProcW+0x1b
001fab64 70ebf5ee comctl32_70e90000!CallOriginalWndProc+0x1a
001fabc8 70ebf5a2 comctl32_70e90000!CallNextSubclassProc+0x3d
001fabec 6494e298 comctl32_70e90000!DefSubclassProc+0x46
001fac34 6494def5 MSO!Ordinal4894+0x74f
001fac60 70ebf5ee MSO!Ordinal4894+0x3ac
001facc4 70ebf490 comctl32_70e90000!CallNextSubclassProc+0x3d
001fad24 766462fa comctl32_70e90000!MasterSubclassProc+0x54
001fad50 76646d3a user32!InternalCallWinProc+0x23
001fadc8 766490c9 user32!UserCallWinProcCheckWow+0x109
001fae58 76646a8c user32!RealDefWindowProcWorker+0x622
001fae78 6d360b64 user32!RealDefWindowProcW+0x4a
001faed4 6d360b96 uxtheme!_ThemeDefWindowProc+0x197
001faef0 7664729a uxtheme!ThemeDefWindowProcW+0x18
001faf38 310249b5 user32!DefWindowProcW+0x68
001fd490 310247b5 WWLIB!DllGetClassObject+0xf361
001fd4d0 766462fa WWLIB!DllGetClassObject+0xf161
001fd4fc 76646d3a user32!InternalCallWinProc+0x23
001fd574 76650d27 user32!UserCallWinProcCheckWow+0x109
001fd5ac 76650d4d user32!CallWindowProcAorW+0xab
001fd5cc 70ebf443 user32!CallWindowProcW+0x1b
001fd5e8 70ebf5ee comctl32_70e90000!CallOriginalWndProc+0x1a
001fd64c 70ebf5a2 comctl32_70e90000!CallNextSubclassProc+0x3d
001fd670 6494e298 comctl32_70e90000!DefSubclassProc+0x46
001fd6b8 6494def5 MSO!Ordinal4894+0x74f
001fd6e4 70ebf5ee MSO!Ordinal4894+0x3ac
001fd748 70ebf490 comctl32_70e90000!CallNextSubclassProc+0x3d
001fd7a8 766462fa comctl32_70e90000!MasterSubclassProc+0x54
001fd7d4 76647316 user32!InternalCallWinProc+0x23
001fd84c 76646de8 user32!UserCallWinProcCheckWow+0xd8
001fd8a8 76648fa7 user32!DispatchClientMessage+0xe0
001fd8e4 7753010a user32!__fnINLPWINDOWPOS+0x2c
001fd988 649aa323 ntdll_77520000!KiUserCallbackDispatcher+0x2e
001fd9b8 3107553b MSO!Ordinal2880+0x2e
001fd9d4 310754eb WWLIB!GetAllocCounters+0x4f0e3
001fd9f8 310754c5 WWLIB!GetAllocCounters+0x4f093
001fda3c 3107476f WWLIB!GetAllocCounters+0x4f06d
001fda78 310746d9 WWLIB!GetAllocCounters+0x4e317
001ffbe8 2fa31625 WWLIB!GetAllocCounters+0x4e281
001ffc0c 2fa315aa WINWORD+0x1625
001ffc9c 769e336a WINWORD+0x15aa
001ffca8 77559f72 kernel32!BaseThreadInitThunk+0xe
001ffce8 77559f45 ntdll_77520000!__RtlUserThreadStart+0x70
001ffd00 00000000 ntdll_77520000!_RtlUserThreadStart+0x1b

 

Example #2

Process Uptime: 0 days 0:02:01.000

0:000:x86> !runaway
User Mode Time
  Thread       Time
   0:2100      0 days 0:01:52.640
   6:1624      0 days 0:00:00.046
   3:2510      0 days 0:00:00.015
  12:21bc      0 days 0:00:00.000
  11:1e4c      0 days 0:00:00.000
  10:15b8      0 days 0:00:00.000
   9:1628      0 days 0:00:00.000
   8:1a90      0 days 0:00:00.000
   7:1060      0 days 0:00:00.000
   5:2664      0 days 0:00:00.000
   4:440       0 days 0:00:00.000
   2:2488      0 days 0:00:00.000
   1:147c      0 days 0:00:00.000
0:000:x86> k
ChildEBP RetAddr 
0040a300 663c0ee0 GdiPlus!DpOutputSpanStretch<1>::OutputSpan+0x361
0040a334 663e9b58 GdiPlus!EpAntialiasedFiller::OutputSpan+0x31
0040a358 663c10ed GdiPlus!DpClipRegion::OutputSpan+0x51
0040a378 663c1e3a GdiPlus!EpAntialiasedFiller::GenerateOutputAndClearCoverage+0x64
0040a3a0 663c0dda GdiPlus!EpAntialiasedFiller::FillEdgesAlternate+0x104
0040a3b8 663c2474 GdiPlus!RasterizeEdges+0xa9
0040ae70 663cb0f6 GdiPlus!RasterizePath+0x2d0
0040b05c 66392054 GdiPlus!DpDriver::DrawImage+0x240
0040b50c 66394718 GdiPlus!GpGraphics::DrvDrawImage+0x215b
0040b604 6639487d GdiPlus!GpGraphics::DrawImage+0x386
0040b668 6635e8da GdiPlus!GpGraphics::DrawImage+0x66
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for MSO.DLL –
0040b6dc 64d1f230 GdiPlus!GdipDrawImagePointsRect+0x1e5
WARNING: Stack unwind information not available. Following frames may be wrong.
0040b74c 64d1f58b MSO!Ordinal1458+0x20b
0040ba40 64d1ef43 MSO!Ordinal1458+0x566
0040ba9c 64d1ee85 MSO!Ordinal8926+0x115
0040baec 64d1bcbf MSO!Ordinal8926+0x57
0040c268 64d1e666 MSO!Ordinal6882+0x6a3
0040c2a4 64d1e5b8 MSO!Ordinal3379+0x214
0040c4f0 64d196fc MSO!Ordinal3379+0x166
0040c518 64d1eeb6 MSO!Ordinal1075+0x2a5d
0040c53c 64d1968e MSO!Ordinal8926+0x88
0040c54c 64d194ff MSO!Ordinal1075+0x29ef
0040d248 64d19363 MSO!Ordinal1075+0x2860
0040d270 64d171e8 MSO!Ordinal1075+0x26c4
0040d37c 64cfb39b MSO!Ordinal1075+0x549
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for WWLIB.DLL –
0040d3e8 50f9e150 MSO!Ordinal423+0x155
0040d4e0 50e051a0 WWLIB!DllGetLCID+0x1b20da
0040d524 50e05169 WWLIB!DllGetLCID+0x1912a
0040d85c 50c9fdee WWLIB!DllGetLCID+0x190f3
0040d94c 50c950b4 WWLIB!GetAllocCounters+0xa9996
0040d97c 50cb980e WWLIB!GetAllocCounters+0x9ec5c
0040d9d4 50c5050c WWLIB!GetAllocCounters+0xc33b6
0040da54 50bf47b5 WWLIB!GetAllocCounters+0x5a0b4
0040da94 766462fa WWLIB!DllGetClassObject+0xf161
0040dac0 76647316 user32!InternalCallWinProc+0x23
0040db38 76646de8 user32!UserCallWinProcCheckWow+0xd8
0040db94 76646e44 user32!DispatchClientMessage+0xe0
0040dbd0 7753010a user32!__fnDWORD+0x2b
0040dc5c 50c463ce ntdll_77520000!KiUserCallbackDispatcher+0x2e
0040dc6c 50e44725 WWLIB!GetAllocCounters+0x4ff76
0040dc84 50c45cad WWLIB!DllGetLCID+0x586af
0040dcac 50c446d9 WWLIB!GetAllocCounters+0x4f855
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for WINWORD.EXE –
0040fe1c 2fe71625 WWLIB!GetAllocCounters+0x4e281
0040fe40 2fe715aa WINWORD+0x1625
0040fed0 769e336a WINWORD+0x15aa
0040fedc 77559f72 kernel32!BaseThreadInitThunk+0xe
0040ff1c 77559f45 ntdll_77520000!__RtlUserThreadStart+0x70
0040ff34 00000000 ntdll_77520000!_RtlUserThreadStart+0x1b

Example #3

Process Uptime: 0 days 0:03:04.000

0:000:x86> Process Uptime: 0 days 0:03:04.000!runaway
User Mode Time
  Thread       Time
   0:2100      0 days 0:02:46.406
   5:1624      0 days 0:00:00.046
   3:2510      0 days 0:00:00.015
  11:2780      0 days 0:00:00.000
  10:21bc      0 days 0:00:00.000
   9:1e4c      0 days 0:00:00.000
   8:15b8      0 days 0:00:00.000
   7:1628      0 days 0:00:00.000
   6:1a90      0 days 0:00:00.000
   4:440       0 days 0:00:00.000
   2:2488      0 days 0:00:00.000
   1:147c      0 days 0:00:00.000
0:000:x86> k
ChildEBP RetAddr 
0040ad1c 663441f6 GdiPlus!FPUStateSaver::Round+0x18
0040ad28 6642c28c GdiPlus!GpRound+0x11
0040ad58 6642cc34 GdiPlus!GpRecolorObject::TransformColor5x5+0x199
0040ad6c 6642d03e GdiPlus!GpRecolorObject::ComputeColorTwist+0x91
0040ad90 66371894 GdiPlus!GpRecolorObject::ColorAdjust+0xfa
0040ada0 664312e1 GdiPlus!GpRecolor::ColorAdjust+0x1e
0040adb4 66430d81 GdiPlus!GpRecolorOp::Run+0x18
0040add8 6643be7d GdiPlus!GpBitmapOps::ReleasePixelDataBuffer+0x8a
0040ae90 6642d31e GdiPlus!GpWicDecoder::Decode+0x169
0040aea4 6642da0f GdiPlus!GpDecodedImage::InternalPushIntoSink+0x2d
0040aebc 6642e571 GdiPlus!GpDecodedImage::PushIntoSink+0x3c
0040af30 66384fc6 GdiPlus!GpMemoryBitmap::InitImageBitmap+0x15f
0040af84 66386c63 GdiPlus!CopyOnWriteBitmap::PipeLockBitsFromDecoder+0xa5
0040b060 66386e69 GdiPlus!CopyOnWriteBitmap::PipeLockBits+0x56b
0040b078 66391df8 GdiPlus!GpBitmap::PipeLockBits+0x50
0040b50c 66394718 GdiPlus!GpGraphics::DrvDrawImage+0x1eff
0040b604 6639487d GdiPlus!GpGraphics::DrawImage+0x386
0040b668 6635e8da GdiPlus!GpGraphics::DrawImage+0x66
0040b6dc 64d1f230 GdiPlus!GdipDrawImagePointsRect+0x1e5
WARNING: Stack unwind information not available. Following frames may be wrong.
0040b74c 64d1f58b MSO!Ordinal1458+0x20b
0040ba40 64d1ef43 MSO!Ordinal1458+0x566
0040ba9c 64d1ee85 MSO!Ordinal8926+0x115
0040baec 64d1bcbf MSO!Ordinal8926+0x57
0040c268 64d1e666 MSO!Ordinal6882+0x6a3
0040c2a4 64d1e5b8 MSO!Ordinal3379+0x214
0040c4f0 64d196fc MSO!Ordinal3379+0x166
0040c518 64d1eeb6 MSO!Ordinal1075+0x2a5d
0040c53c 64d1968e MSO!Ordinal8926+0x88
0040c54c 64d194ff MSO!Ordinal1075+0x29ef
0040d248 64d19363 MSO!Ordinal1075+0x2860
0040d270 64d171e8 MSO!Ordinal1075+0x26c4
0040d37c 64cfb39b MSO!Ordinal1075+0x549
0040d3e8 50f9e150 MSO!Ordinal423+0x155
0040d4e0 50e051a0 WWLIB!DllGetLCID+0x1b20da
0040d524 50e05169 WWLIB!DllGetLCID+0x1912a
0040d85c 50c9fdee WWLIB!DllGetLCID+0x190f3
0040d94c 50c950b4 WWLIB!GetAllocCounters+0xa9996
0040d97c 50cb980e WWLIB!GetAllocCounters+0x9ec5c
0040d9d4 50c5050c WWLIB!GetAllocCounters+0xc33b6
0040da54 50bf47b5 WWLIB!GetAllocCounters+0x5a0b4
0040da94 766462fa WWLIB!DllGetClassObject+0xf161
0040dac0 76647316 user32!InternalCallWinProc+0x23
0040db38 76646de8 user32!UserCallWinProcCheckWow+0xd8
0040db94 76646e44 user32!DispatchClientMessage+0xe0
0040dbd0 7753010a user32!__fnDWORD+0x2b
0040dc5c 50c463ce ntdll_77520000!KiUserCallbackDispatcher+0x2e
0040dc6c 50e44725 WWLIB!GetAllocCounters+0x4ff76
0040dc84 50c45cad WWLIB!DllGetLCID+0x586af
0040dcac 50c446d9 WWLIB!GetAllocCounters+0x4f855
0040fe1c 2fe71625 WWLIB!GetAllocCounters+0x4e281
0040fe40 2fe715aa WINWORD+0x1625
0040fed0 769e336a WINWORD+0x15aa
0040fedc 77559f72 kernel32!BaseThreadInitThunk+0xe
0040ff1c 77559f45 ntdll_77520000!__RtlUserThreadStart+0x70
0040ff34 00000000 ntdll_77520000!_RtlUserThreadStart+0x1b

We can see we are dealing with graphics library.

0:000:x86> lmvm gdiplus
start             end                 module name
66320000 664b0000   GdiPlus    (pdb symbols)          c:\symbols\MicrosoftWindowsGdiPlus-1.1.7601.17514-gdiplus.pdb\999409491C874F1DAA3DBBD44C54AC201\MicrosoftWindowsGdiPlus-1.1.7601.17514-gdiplus.pdb
    Loaded symbol image file: GdiPlus.dll
    Image path: C:\Windows\winsxs\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.17514_none_72d18a4386696c80\GdiPlus.dll
    Image name: GdiPlus.dll
    Timestamp:        Sat Nov 20 22:55:00 2010 (4CE7B714)
    CheckSum:         00191664
    ImageSize:        00190000
    File version:     6.1.7601.17514
    Product version:  6.1.7601.17514
    File flags:       0 (Mask 3F)
    File OS:          40004 NT Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0409.04b0
    CompanyName:      Microsoft Corporation
    ProductName:      Microsoft® Windows® Operating System
    InternalName:     gdiplus
    OriginalFilename: gdiplus
    ProductVersion:   6.1.7601.17514
    FileVersion:      6.1.7601.17514 (win7sp1_rtm.101119-1850)
    FileDescription:  Microsoft GDI+
    LegalCopyright:   © Microsoft Corporation. All rights reserved.

 

The issue is reported as image is not always showing correctly and there is some kind of image processing going on. Let’s see if we can extract the image from the DMP file.

We’ll start and check if any JPEGs are loaded, to do this we will search process memory for the JPEG file header which is bytes FF D8 FF E0 00 10 4A 46 49 46:

0:000:x86> s 0 L?80000000 FF D8 FF E0 00 10 4A 46 49 46
06950000  ff d8 ff e0 00 10 4a 46-49 46 00 01 02 01 04 b0  ……JFIF……

Now we need to find the JPEG “end of file” marker is which is bytes FF D9

0:000:x86> s -[sn1]b 06950000 L?80000000 FF D9
06d756dd  ff d9 00 00 00 00 00 00-00 00 00 00 00 00 00 00  …………….
                                             ^ Overflow error in ‘s -[sn1]b 06950000 l?80000000 FF D9′

The overflow error is expected, because we used sn1 to return a single result. Now we just need to add 2 to 06d756dd to have our ending address. Now we just need to write out the file

0:000:x86> .writemem c:\support\jpg1.jpg 6950000 L?(06d756dd+2-06950000)
Writing 4256df bytes

We need to use L? in this case due the range being greater than 1 MB in size.

The image extracts fine, and we look at properties can see it is very high resolution image 9,922 x 14,032 pixels.

image

Reducing the image size in document fixed the issue.

Posted in Citrix, Office, WinDbg | Tagged | Leave a comment