[ros-dev] Bye bye

Hartmut Birr osexpert at googlemail.com
Wed Jan 18 20:59:38 CET 2006

Steven Edwards wrote:
> Hi,
> On 1/17/06, Hartmut Birr <osexpert at googlemail.com> wrote:
>> Sometimes in the past, I didn't understand some changes, because the
>> code didn't make sense for the current state of reactos and was not
>> used. Currently, I've compared disassembled code from win2k and winxp
>> with ReactOS. In my opinion, some of the developers do disassemble
>> windows code to implement ReactOS.
> Can you list offending code with a list of svn commits?
> Thanks
> --
> Steven Edwards - ReactOS and Wine developer


some days ago, I've seen the bug from r20911. It triggers a page fault
after an invalid opcode exception from v86 mode. The invalid opcode
exception in v86 mode can only occur if it is a real exception or if
someone does setup a frame and calls the trap handler directly. I've
found the function BadStack and some other things in syscall.S. The
BadStack function don't make sense a the current state of ReactOS. I've
compared the KiSysCallEntry with the dissembled code from WinXP:

004xxxxx                    off_004xxxxx:
004xxxxx B923000000             mov     ecx,23h
004xxxxx 6A30                   push    30h
004xxxxx 0FA1                   pop     fs
004xxxxx 8ED9                   mov     ds,ecx
004xxxxx 8EC1                   mov     es,ecx
004xxxxx 648B0D40000000         mov     ecx,fs:[40h]
004xxxxx 8B6104                 mov     esp,[ecx+4]
004xxxxx 6A23                   push    23h
004xxxxx 52                     push    edx
004xxxxx 9C                     pushfd
004xxxxx                    loc_004xxxxxx:
004xxxxx 6A02                   push    2
004xxxxx 83C208                 add     edx,8
004xxxxx 9D                     popfd
004xxxxx 804C240102             or      byte ptr [esp+1],2
004xxxxx 6A1B                   push    1Bh
004xxxxx FF350403DFFF           push    dword ptr [0FFDF0304h]
004xxxxx 6A00                   push    0
004xxxxx 55                     push    ebp
004xxxxx 53                     push    ebx
004xxxxx 56                     push    esi
004xxxxx 57                     push    edi
004xxxxx 648B1D1C000000         mov     ebx,fs:[1Ch]
004xxxxx 6A3B                   push    3Bh
004xxxxx 8BB324010000           mov     esi,[ebx+124h]
004xxxxx FF33                   push    dword ptr [ebx]
004xxxxx C703FFFFFFFF           mov     dword ptr [ebx],0FFFFFFFFh
004xxxxx 8B6E18                 mov     ebp,[esi+18h]
004xxxxx 6A01                   push    1
004xxxxx 83EC48                 sub     esp,48h
004xxxxx 81ED9C020000           sub     ebp,29Ch
004xxxxx C6864001000001         mov     byte ptr [esi+140h],1
004xxxxx 3BEC                   cmp     ebp,esp
004xxxx1 0F85xxxxFFFF           jne     loc_004xxxx2
004xxxxx 83652C00               and     dword ptr [ebp+2Ch],0
004xxxxx F6462CFF               test    byte ptr [esi+2Ch],0FFh
004xxxxx 89AE34010000           mov     [esi+134h],ebp
004xxxxx 0F85xxxxFFFF           jne     loc_004xxxxx
004xxxxx                    loc_004xxxxx:
004xxxxx 8B5D60                 mov     ebx,[ebp+60h]
004xxxxx 8B7D68                 mov     edi,[ebp+68h]
004xxxxx 89550C                 mov     [ebp+0Ch],edx
004xxxx3 C74508000DDBBA         mov     dword ptr [ebp+8],0BADB0D00h
004xxxxx 895D00                 mov     [ebp],ebx
004xxxxx 897D04                 mov     [ebp+4],edi
004xxxxx FB                     sti

004xxxx2                    loc_004xxxx2:
004xxxxx 648B0D40000000         mov     ecx,fs:[40h]
004xxxxx 8B6104                 mov     esp,[ecx+4]
004xxxxx 6A00                   push    0
004xxxxx 6A00                   push    0
004xxxxx 6A00                   push    0
004xxxxx 6A00                   push    0
004xxxxx 6A23                   push    23h
004xxxxx 6A00                   push    0
004xxxxx 6802020200             push    20202h
004xxxxx 6A1B                   push    1Bh
004xxxxx 6A00                   push    0
004xxxxx E9xxxx0000             jmp     loc_00407F1A

80064375 <_KiFastCallEntry>:

    /* Set FS to PCR */
    mov ecx, KGDT_R0_PCR
80064375:    b9 30 00 00 00           mov    $0x30,%ecx
    mov fs, cx
8006437a:    8e e1                    movl   %ecx,%fs

    /* Set DS/ES to Kernel Selector */
    mov ecx, KGDT_R0_DATA
8006437c:    b9 10 00 00 00           mov    $0x10,%ecx
    mov ds, cx
80064381:    8e d9                    movl   %ecx,%ds
    mov es, cx
80064383:    8e c1                    movl   %ecx,%es

    /* Set the current stack to Kernel Stack */
    mov ecx, [fs:KPCR_TSS]
80064385:    64 8b 0d 40 00 00 00     mov    %fs:0x40,%ecx
    mov esp, ss:[ecx+KTSS_ESP0]
8006438c:    36 8b 61 04              mov    %ss:0x4(%ecx),%esp

    /* Set up a fake INT Stack. */
    push KGDT_R3_DATA + RPL_MASK
80064390:    6a 23                    push   $0x23
    push edx                            /* Ring 3 SS:ESP */
80064392:    52                       push   %edx
    pushf                               /* Ring 3 EFLAGS */
80064393:    9c                       pushf 
    push 2                              /* Ring 0 EFLAGS */
80064394:    6a 02                    push   $0x2
    add edx, 8                          /* Skip user parameter list */
80064396:    83 c2 08                 add    $0x8,%edx
    popf                                /* Set our EFLAGS */
80064399:    9d                       popf  
    or dword ptr [esp], EFLAGS_INTERRUPT_MASK   /* Re-enable IRQs in
EFLAGS, to fake INT */
8006439a:    81 0c 24 00 02 00 00     orl    $0x200,(%esp)
    push KGDT_R3_CODE + RPL_MASK
800643a1:    6a 1b                    push   $0x1b
800643a3:    68 04 03 fe 7f           push   $0x7ffe0304

    /* Setup the Trap Frame stack */
    push 0
800643a8:    6a 00                    push   $0x0
    push ebp
800643aa:    55                       push   %ebp
    push ebx
800643ab:    53                       push   %ebx
    push esi
800643ac:    56                       push   %esi
    push edi
800643ad:    57                       push   %edi
    push KGDT_R3_TEB + RPL_MASK
800643ae:    6a 3b                    push   $0x3b

    /* Save pointer to our PCR */
    mov ebx, [fs:KPCR_SELF]
800643b0:    64 8b 1d 1c 00 00 00     mov    %fs:0x1c,%ebx

    /* Get a pointer to the current thread */
    mov esi, [ebx+KPCR_CURRENT_THREAD]
800643b7:    8b b3 24 01 00 00        mov    0x124(%ebx),%esi

    /* Set the exception handler chain terminator */
    push [ebx+KPCR_EXCEPTION_LIST]
800643bd:    ff 33                    pushl  (%ebx)
    mov dword ptr [ebx+KPCR_EXCEPTION_LIST], -1
800643bf:    c7 03 ff ff ff ff        movl   $0xffffffff,(%ebx)

    /* Use the thread's stack */
    mov ebp, [esi+KTHREAD_INITIAL_STACK]
800643c5:    8b 6e 18                 mov    0x18(%esi),%ebp

    /* Push previous mode */
    push UserMode
800643c8:    6a 01                    push   $0x1

    /* Skip the other registers */
    sub esp, 0x48
800643ca:    83 ec 48                 sub    $0x48,%esp

    /* Hack: it seems that on VMWare someone damages ES/DS on exit.
Investigate! */
    mov dword ptr [esp+KTRAP_FRAME_DS], KGDT_R3_DATA + RPL_MASK
800643cd:    c7 44 24 38 23 00 00     movl   $0x23,0x38(%esp)
800643d4:    00
    mov dword ptr [esp+KTRAP_FRAME_ES], KGDT_R3_DATA + RPL_MASK
800643d5:    c7 44 24 34 23 00 00     movl   $0x23,0x34(%esp)
800643dc:    00

    /* Make space for us on the stack */
    sub ebp, 0x29C
800643dd:    81 ed 9c 02 00 00        sub    $0x29c,%ebp

    /* Write the previous mode */
    mov byte ptr [esi+KTHREAD_PREVIOUS_MODE], UserMode
800643e3:    c6 86 d7 00 00 00 01     movb   $0x1,0xd7(%esi)

    /* Sanity check */
    cmp ebp, esp
800643ea:    39 e5                    cmp    %esp,%ebp
    jnz BadStack
800643ec:    0f 85 5e ff ff ff        jne    80064350 <BadStack>

    /* Flush DR7 */
    and dword ptr [ebp+KTRAP_FRAME_DR7], 0
800643f2:    83 65 2c 00              andl   $0x0,0x2c(%ebp)

    /* Check if the thread was being debugged */
    test byte ptr [esi+KTHREAD_DEBUG_ACTIVE], 0xFF
800643f6:    f6 46 03 ff              testb  $0xff,0x3(%esi)

    /* Jump to shared code or DR Save */
    //jnz Dr_FastCallDrSave
    jmp SharedCode
800643fa:    eb 5b                    jmp    80064457 <SharedCode>

    mov [esi+KTHREAD_TRAP_FRAME], ebp
80064457:    89 ae 10 01 00 00        mov    %ebp,0x110(%esi)

    /* Set the trap frame debug header */
8006445d:    8b 5d 60                 mov    0x60(%ebp),%ebx
80064460:    8b 7d 68                 mov    0x68(%ebp),%edi
80064463:    89 55 0c                 mov    %edx,0xc(%ebp)
80064466:    c7 45 08 00 0d db ba     movl   $0xbadb0d00,0x8(%ebp)
8006446d:    89 5d 00                 mov    %ebx,0x0(%ebp)
80064470:    89 7d 04                 mov    %edi,0x4(%ebp)

80064350 <BadStack>:
80064350:    64 8b 0d 40 00 00 00     mov    %fs:0x40,%ecx
80064357:    36 8b 61 04              mov    %ss:0x4(%ecx),%esp
8006435b:    6a 00                    push   $0x0
8006435d:    6a 00                    push   $0x0
8006435f:    6a 00                    push   $0x0
80064361:    6a 00                    push   $0x0
80064363:    6a 23                    push   $0x23
80064365:    6a 00                    push   $0x0
80064367:    68 02 02 02 00           push   $0x20202
8006436c:    6a 1b                    push   $0x1b
8006436e:    6a 00                    push   $0x0
80064370:    e9 1f 0c 00 00           jmp    80064f94 <_KiTrap6>

The ReactOS code and the WinXP code is nearly the same. The stack check
and the invalid opcode exception is equal. The trap frame is created in
the same sequence. The debug mark 0xbadb0d00 is the same. On other
places we use always something like 0xdeadbeef or 0xceadbeef. Each
revision of syscall.S makes our code closer to the Windows code. In some
days we have exactly the same binary code. I know that the frame,
KTHREAD and the PCR layout is predefined. Some of the used informations
are not public. In my opinion, the fast call entry code is copied step
by step from the disassembled Windows code.

- Hartmut

More information about the Ros-dev mailing list