Results 1 to 8 of 8

Thread: Possible DoS with Int 2D in softice

  1. #1

    Possible DoS with Int 2D in softice

    I came across this warning about softice and Int 2D:

    http://www.derkeiler.com/Mailing-Lists/Securiteam/2005-05/0166.html

    I did a reasonable search of the archives and came across Kayaker's post on video problems with softice. He mentioned a patch for Int 2D, but it seemed aimed at video problems. I'm wondering if maybe the patch process mentioned in Kayakers article was aimed more at this denial of service possibility? If so, should it maybe be applied generally, even if your video is working fine in softice?

    I'm wondering also about problems some people have complained about where softice crashes for no apparent reason. Has this Int 2D problem been mentioned before in this capacity?

  2. #2
    Registered User
    Join Date
    Feb 2004
    Location
    France
    Posts
    99
    Hello,

    I studied the problem a while ago ,when it was dicovered by Piotr Bania. I paste some of my comments that I discussed with my team mates. (sorry if the translation is awfull, english is not my native language).

    AFAIK it is not related to a video problem but as the paper says, with debug message.

    the int 2D is hooked by DbgMsg.sys (part of DriverStudio) even if softice is not active.

    Here's a simple look at int 2D with the Kernel debugger (softice is not active):

    Code:
    kd> !idt 2d
    
    Dumping IDT:
    
    2d:     b8d93b5c *** ERROR: Module load completed but symbols could not be loaded for DbgMsg.SYS
    
    DbgMsg+0xB5C
    On any system with Driver studio installed a simple code like this will bring a BSOD :

    Code:
    mov eax, 1
    xor ecx, ecx
    xor edx ,edx
    
    int 2Dh


    Normally a call to int 2D is issued when calling DbgPrint :

    Code:
       invoke LoadLibrary, addr ntdll ; "ntdll"
       invoke GetProcAddress,eax, addr DbgPrint
       push 12345678h; value to convert
       push offset Format ; "converted value is %lu" [our format string]
       call eax ; call DbgPrint func
    in DbgPrint a call is made to _vnsprintf which then call the int2D (somewhere in NTDLL) :

    Code:
    7C93057E              8B45 08            MOV     EAX,DWORD PTR SS:[EBP+8]                           ;   1 : service number
    7C930581          |.  8B4D 0C            MOV     ECX,DWORD PTR SS:[EBP+C]                           ;  pointer on stack : "converted value is 305419896"
    7C930584          |.  8B55 10            MOV     EDX,DWORD PTR SS:[EBP+10]                          ;   0x1C : length of string
    7C930587          |.  8B5D 14            MOV     EBX,DWORD PTR SS:[EBP+14]                          ;   -1
    7C93058A          |.  8B7D 18            MOV     EDI,DWORD PTR SS:[EBP+18]                          ;   0
    7C93058D          |.  CD 2D              INT     2D
    7C93058F          |.  CC                 INT3
    7C930590          |.  5B                 POP     EBX
    We then switch to ring0 and go to DbgMsg.sys. The problem lies around here, in an inlined strlen :

    Code:
    .text:00010DE0 000                 push    ebp
    .text:00010DE1 004                 mov     ebp, esp
    .text:00010DE3 004                 push    ecx
    .text:00010DE4 008                 mov     eax, [ebp+arg_0] ; buffer of the formated string (in context of the ring3 process, this address is the one from the stack of the calling process)
    .text:00010DE7 008                 push    ebx
    .text:00010DE8 00C                 push    esi
    .text:00010DE9 010                 mov     esi, ecx
    .text:00010DEB 010                 push    edi
    .text:00010DEC 014                 lea     ecx, [eax+1] ; address of the next char in the string
    .text:00010DEF 014                 xor     ebx, ebx
    .text:00010DF1     
    .text:00010DF1     loc_10DF1:                              ; CODE XREF: sub_10DE0+16j
    .text:00010DF1 014                 mov     dl, [eax] ; !!!!!!!!!
    If you remember what we've done previously to get the BSOD (passing 0 as the adress of the buffer), you'll kickly see that that DbgMsg.sys is trying to reference the 0 address... leading to a BSOD :

    Code:
    .text:00010DF1 014                 mov     dl, [eax] ; EAX = 0 ? ouch !!!!
    To be patched, this problem requires a patching in this DbgMsg.sys function to check if the adress passed by the caller is valid and then can be referenced. Checking only for 0 isn't sufficient...

    Maybe calling MmIsAddressValid function could do the trick but i haven't tested it...

    I would be glad if someone has an idea on how to patch this flaw
    Last edited by Neitsa; November 24th, 2006 at 12:24.
    Omne tulit punctum qui miscuit utile dulci

  3. #3
    well u did like 1/2 the work
    a simple patch checking for eax != 0 or mmisaddressvalid call could be done via detouring the mov dl,[eax] to the checking code.. hardly rocket science patching that

  4. #4
    Quote Originally Posted by Neitsa View Post
    I studied the problem a while ago ,when it was dicovered by Piotr Bania. I paste some of my comments that I discussed with my team mates. (sorry if the translation is awfull, english is not my native language).
    Hi Neitsa...thanks for the detailed reply. Your English is OK...I understand what you are saying, with no effort.

    Quote Originally Posted by Neitsa View Post
    AFAIK it is not related to a video problem but as the paper says, with debug message.
    This is Kayakers article:

    http://www.woodmann.com/forum/showthread.php?t=7199&highlight=kayaker+video

    Half way through it, you can see a reference to INT 2D that covers points 6 to 13. It talks about an INT 2D 'patch', and I think that info comes from NuMega/Compuware. Kayaker will probably check in, but if he doesn't, I'll PM him to see if he can elaborate.

    I also found this interesting article from Dr. Dobb's journal:

    http://www.ddj.com/dept/windows/184416239

    It is written by Joe Flores, a programmer for NuMega. He claims INT 2D is used by the NT debugging service to transfer control to service routines. I'm just wondering if the alterations to the registry in Kayakers post could affect the way INT 2D operates. As you and evlncrn8 pointed out, fixing the problem would require alterations to the code. I'm wondering if NuMega had a way of doing it via the registry. I don't see how, yet I'm wondering why they call it a patch.

    I'll need some time to digest the rest of your reply. I'm slowly getting into lower-level routines, but I need to read so much to understand a little.

    thanks again for your response.

  5. #5
    Quote Originally Posted by evlncrn8 View Post
    well u did like 1/2 the work
    a simple patch checking for eax != 0 or mmisaddressvalid call could be done via detouring the mov dl,[eax] to the checking code.. hardly rocket science patching that
    Howdy...thanks for reply. Are you talking about a patch that requires a jump to a pocket in the code where you insert your own code, or something simpler?

  6. #6
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Posts
    4,047
    Blog Entries
    5
    Thanks for the link Waxford. I saw a reference to that article earlier today but didn't have time to dig up the article itself. Here's the other interesting paper where I saw it linked:

    Tracing NT Kernel-Mode Calls
    http://www.ddj.com/dept/windows/184416246

    As mentioned the trick behind it all is that you can hook Int2D to monitor system module loading. In XP you can use PsSetLoadImageNotifyRoutine, which serves the same purpose in a very similar location.

    I did look into the Numega Int2D patch to see what it did, I more or less followed the instructions in step 13 as per the forum thread you linked.

    I searched for the bytes
    "s MmLoadSystemImage L d88 85,c0,0f,84"

    This search method as described isn't valid for WinXP or Win2Ksp4, for example the symbol is actually "_MmLoadSystemImage" in XP and you need to find a different way of getting into ntoskrnl context for a symbol based search to work.

    The bytes 85,c0,0f,84 code for the instructions
    test eax, eax
    jz xxxxxxxx

    If you search as described in the official Numega solution you won't find the right address for these very common instructions and will end up patching the wrong place in ntoskrnl (which is what I did at first), woe to the unwary XP user!

    However, they do give an absolute Int2D patch address of 0x804c2b95 for Win2Ksp4, and this is correct. From this I was able to determine the patch point is actually within the function CacheImageSymbols, which is called from MmLoadSystemImage.


    Here is some pseudocode which describes what happens within MmLoadSystemImage. What is important is that the Int2D patch patches CacheImageSymbols so that it ALWAYS returns true. This forces DbgLoadImageSymbols to be called no matter what, whenever a system image is loaded. DbgLoadImageSymbols in turn calls the Int2D interrupt which leads into the ntice driver DbgMsg.sys and also into siwvid.sys where the graphic adapters listed under NTICE in the registry are checked. This may be the relationship to Softice and video issues.

    Code:
    if (PsImageNotifyEnabled == TRUE)
    {  
         PsCallImageNotifyRoutines(...);
    }
    
    if (CacheImageSymbols(ImageBase) == TRUE)
    // Int2D patch applied always returns TRUE
    {  
         DbgLoadImageSymbols(ULONG ImageBase, PSTRING ModuleName, -1);
    }
    
    ... continue driver/module loading

    If we look into the CacheImageSymbols function itself we can see the exact patch point, which matches the search bytes:

    Code:
    :u 804c2b57 L 5e
    _CacheImageSymbols
    :804C2B57                     PUSH      EBP
    ...
    :804C2B85                     PUSH      EAX
    :804C2B86                     PUSH      06   // IMAGE_DIRECTORY_ENTRY_DEBUG
    :804C2B88                     PUSH      01
    :804C2B8A                     PUSH      DWORD PTR [EBP+08]
    :804C2B8D                     CALL      _RtlImageDirectoryEntryToData
    :804C2B92                     MOV       [EBP-1C],EAX
    :804C2B95  85C0               TEST      EAX,EAX
    :804C2B97  0F8406DA0200       JZ       804F05A3
    :804C2B9D                     OR        DWORD PTR [EBP-04],-01
    :804C2BA1                     PUSH      01
    :804C2BA3                     POP       EAX
    :804C2BA4                     MOV       ECX,[EBP-10]
    :804C2BA7                     MOV       FS:[00000000],ECX
    :804C2BAE                     POP       EDI
    :804C2BAF                     POP       ESI
    :804C2BB0                     POP       EBX
    :804C2BB1                     LEAVE
    :804C2BB2                     RET       0004 
    
    :u 804f05a3 L 0e
    :804F05A3              OR        DWORD PTR [EBP-04],-01
    :804F05A7                     XOR       EAX,EAX
    :804F05A9                     JMP      804C2BA4
    Having found this address you can create the NTICE registry entries:
    "DoInt2dPatch"=dword:00000001
    "Int2dLocation"=dword:804C2B95

    When activated, you will find all the Int2D patch does is to insert 8 nops, overwriting the 'test eax, eax - jz' instructions. So what you get is:
    Code:
    :804C2B8D                     CALL      _RtlImageDirectoryEntryToData
    :804C2B92                     MOV       [EBP-1C],EAX
    :804C2B95                     nop nop
    :804C2B97                     nop nop nop nop nop nop
    :804C2B9D                     OR        DWORD PTR [EBP-04],-01

    The following code should explain what RtlImageDirectoryEntryToData does:

    Code:
    #define IMAGE_DIRECTORY_ENTRY_DEBUG           6   // Debug Directory
    
    typedef struct _IMAGE_DEBUG_DIRECTORY {
        DWORD   Characteristics;
        DWORD   TimeDateStamp;
        WORD    MajorVersion;
        WORD    MinorVersion;
        DWORD   Type;
        DWORD   SizeOfData;
        DWORD   AddressOfRawData;
        DWORD   PointerToRawData;
    } IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY;
    
    // Look up the IMAGE_DEBUG_DIRECTORY directory in the IMAGE_OPTIONAL_HEADER.DataDirectory
    pImageDebugDir = (PIMAGE_DEBUG_DIRECTORY) RtlImageDirectoryEntryToData(
    			(PVOID) BaseAddress,          // IN PVOID	Base
    			1,                            // BOOLEAN	MappedAsImage
    			IMAGE_DIRECTORY_ENTRY_DEBUG,  // ULONG		DirectoryEntry
    			&size                         // PULONG		Size
    			);
    So it appears that the Int2D patch is just making sure that CacheImageSymbols returns successfully, even if RtlImageDirectoryEntryToData doesn't find a valid IMAGE_DEBUG_DIRECTORY pointer. In other words if a driver or other loadable system image was compiled in Release mode rather than Debug mode. The IMAGE_DEBUG_DIRECTORY pointer is never used anyway, it's just a way of forcing all images to go through Softice's Int2D handler.


    If you're interested, there is Int2D patch code in the INIT section of ntice.sys, a string search for "DoInt2DPatch" etc. makes it easy to find. The Int2D handler (and others) can be found in this code (for DS3.2, do a search for the SIDT instruction otherwise). Or just break on DbgLoadImageSymbols and start tracing!

    Code:
    :00015215        HookInterrupts  proc near     ; CODE XREF: start__+A8
    
    :00015215 60                                      pusha
    :00015216 8B EC                                   mov     ebp, esp
    :00015218 83 EC 08                                sub     esp, 8
    :0001521B 66 8C 25 09 05 0F 00                    mov     word_F0509, fs
    :00015222 0F 01 4D F8                             sidt    [ebp+var_8]
    ...
    :000152D4 B8 2D 00 00 00                          mov     eax, 2Dh
    :000152D9 B2 60                                   mov     dl, 60h
    :000152DB BF C1 82 0A 00                          mov     edi, offset Int2D_Handler
    :000152E0 E8 C2 01 00 00                          call    HookInt

    Finally, if you want to do the Int2D patch for XPsp2, the patch point is a bit different. Same byte sequence, different location. Now it's immediately *after* the CacheImageSymbols call rather than *within* it:

    Code:
    :004CF1EA 80 3D 34 5F 5B 00 00                    cmp     ds:_PsImageNotifyEnabled, 0
    :004CF1F1 0F 85 26 AB 04 00                       jnz     loc_519D1D
    :004CF1F7
    :004CF1F7 loc_4CF1F7:        ; CODE XREF: MmLoadSystemImage(x,x,x,x,x,x)+4B0B5
    :004CF1F7 FF 37                                   push    dword ptr [edi] ; ImageBase
    :004CF1F9 E8 5D 0C 00 00                          call    _CacheImageSymbols@4
    
    // Int2D patch address is here
    :004CF1FE 85 C0                                   test    eax, eax
    :004CF200 0F 84 81 00 00 00                       jz      loc_4CF287
    
    :004CF206 66 83 7D CC 16                          cmp     [ebp+Destination.Length], 16h
    :004CF20B 0F 86 48 AB 04 00                       jbe     loc_519D59
    :004CF211 6A 0B                                   push    0Bh             ; size_t
    :004CF213 68 0C F3 4C 00                          push    offset off_4CF30C ; wchar_t *
    :004CF218 FF 75 D0                                push    [ebp+Destination.Buffer] ; wchar_t *
    :004CF21B E8 6F C6 F4 FF                          call    __wcsnicmp
    :004CF220 83 C4 0C                                add     esp, 0Ch
    :004CF223 85 C0                                   test    eax, eax
    :004CF225 0F 85 2E AB 04 00                       jnz     loc_519D59
    :004CF22B 8B 45 CC                                mov     eax, dword ptr [ebp+Destination.Length]
    :004CF22E 89 85 40 FF FF FF                       mov     [ebp+var_C0], eax
    :004CF234 8B 45 D0                                mov     eax, [ebp+Destination.Buffer]
    :004CF237 83 C0 16                                add     eax, 16h
    :004CF23A 89 85 44 FF FF FF                       mov     [ebp+var_BC], eax
    :004CF240 66 83 85 40 FF FF FF EA                 add     word ptr [ebp+var_C0], 0FFEAh
    :004CF248 8D 85 40 FF FF FF                       lea     eax, [ebp+var_C0]
    :004CF24E 50                                      push    eax
    :004CF24F 68 34 00 DF FF                          push    0FFDF0034h
    :004CF254 68 24 F3 4C 00                          push    offset aWsWz_0  ; "%ws%wZ"
    :004CF259 FF 75 A0                                push    [ebp+P]         ; char *
    :004CF25C E8 CC 53 F6 FF                          call    _sprintf
    :004CF261 83 C4 10                                add     esp, 10h
    :004CF264
    :004CF264     loc_4CF264:  ; CODE XREF: MmLoadSystemImage(x,x,x,x,x,x)+4B0CE
    :004CF264 FF 75 A0                                push    [ebp+P]         ; SourceString
    :004CF267 8D 85 D0 FE FF FF                       lea     eax, [ebp+DestinationString]
    :004CF26D 50                                      push    eax             ; DestinationString
    :004CF26E E8 4A 31 F3 FF                          call    _RtlInitString@8 ; RtlInitString(x,x)
    :004CF273 6A FF                                   push    0FFFFFFFFh      ; int
    :004CF275 FF 37                                   push    dword ptr [edi] ; ImageBase
    :004CF277 8D 85 D0 FE FF FF                       lea     eax, [ebp+DestinationString]
    :004CF27D 50                                      push    eax             ; int
    :004CF27E E8 1E 56 F6 FF                          call    _DbgLoadImageSymbols@12

    On my XPsp2 system the CacheImageSymbols address is 0x805A61F9, and the Int2D patch address would be 0x805A61FE.
    So you would create the following registry entries and *then* either start Softice manually or reboot.
    \REGISTRY\Machine\System\ControlSet\Services\NTice
    "DoInt2dPatch"=dword:00000001
    "Int2dLocation"=dword:805A61FE


    Phew that was long, I guess I should update that "Official tech support - Configuring Softice to work on all video cards" thread to link to this one for proper implementation of the Int2D patch..

    Kayaker

  7. #7
    Registered User
    Join Date
    Feb 2004
    Location
    France
    Posts
    99
    Thanks a lot Kayaker, that's a very interesting post !

    I'll have to study and trace the code to understand it fully, though
    Omne tulit punctum qui miscuit utile dulci

  8. #8
    Quote Originally Posted by Kayaker View Post
    Thanks for the link Waxford. I saw a reference to that article earlier today but didn't have time to dig up the article itself. Here's the other interesting paper where I saw it linked:
    Kayaker...your welcome for the link, and thanks for yours. Also, thanks for your hard work in the reply, and sorry for the lateness of my reply. It was late at night when I first saw it, and not much was sinking in.

    I've been dickering around with softice, but more in relationship to my other post, to which you replied. It's the one in the newbie forum about 'access violations and other dirty deeds'. I'm going to update that one, and I'd appreciate your consideration of what I have learned.

    Some of it raised further questions about softice in XP SP2 with regard to the BPM command. I want to get into the current issue about the INT 2D, but the access violations have me consumed. Also, I'm in the middle of Silver's DX crackme.

    Like Neitsa, I need to sit down with your reply for a bit, but your info for XP was of immediate interest..

Similar Threads

  1. to softice or not to softice
    By WaxfordSqueers in forum Tools of Our Trade (TOT) Messageboard
    Replies: 19
    Last Post: December 31st, 2007, 17:41
  2. softice help
    By god in forum The Newbie Forum
    Replies: 13
    Last Post: January 23rd, 2006, 00:53
  3. softice help
    By PETER in forum Tools of Our Trade (TOT) Messageboard
    Replies: 2
    Last Post: September 11th, 2002, 06:31
  4. Doing it without softice
    By blink4me in forum Advanced Reversing and Programming
    Replies: 8
    Last Post: July 5th, 2002, 23:32
  5. softice
    By Dan in forum Tools of Our Trade (TOT) Messageboard
    Replies: 1
    Last Post: October 30th, 2001, 00:33

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •