GetCommandLine issue with Dungeon Keeper

Andreas Rosenberg sonix2003 at ctf-z.de
Mon Jan 19 14:34:54 CST 2004


>  From my notes (I dont have Linux to hand just now):
> Trap occurs ar 0x43d4e2
> At this point in time the path/exe is in 0x552150 On windows:
> This was copied from 0x12fe20 (Was already filled in at a breakpoint at
> 0x43d4ba)
> which in turn came from 0x141ee0 when the pgm is very first loaded
> (windbg or msdev prior to executing any code).

Here is the output of IDA pro after detecting the compiler (Visual C familiy).
So it could detect the C lib functions. Now it is nearly obvious how the bug 
happens:

The result of GetCommandLine is being copied into a buffer. Then the command line
is being broken down into an array of char pointers. This array is being passed
to the subroutine below. There the first element is being "sprintf"ed into a 
buffer from the BSS segment. After that the strrchr searches for a '\'.
No check is performed if a '\' is found.

----------------------------------------
I found an interesting note in the MS documentation regarding GetCommandLine:

Note:  The name of the executable in the command line that the operating system provides to a process is not necessarily identical to that in the command line that the calling process gives to the CreateProcess function. The operating system may prepend a fully qualified path to an executable name that is provided without a fully qualified path.
----------------------------------------

.text:004D25C0 ; __stdcall WinMain(x,x,x,x)
.text:004D25C0 _WinMain at 16     proc near               ; CODE XREF: start+159p
.text:004D25C0
.text:004D25C0 arg_0           = dword ptr  4
.text:004D25C0
.text:004D25C0                 mov     eax, [esp+arg_0]
.text:004D25C4                 push    103h            ; size_t
.text:004D25C9                 mov     hInstance, eax
.text:004D25CE                 call    ds:GetCommandLineA
.text:004D25D4                 push    eax             ; char *
.text:004D25D5                 push    offset PtrCommandLine ; char *
.text:004D25DA                 call    _strncpy
.text:004D25DF                 add     esp, 0Ch
.text:004D25E2                 mov     ecx, offset PtrCommandLine
.text:004D25E7                 mov     CounterArgs, 0
.text:004D25F0
.text:004D25F0 loc_4D25F0:                             ; CODE XREF: WinMain(x,x,x,x)+4Aj
.text:004D25F0                                         ; WinMain(x,x,x,x)+7Aj ...
.text:004D25F0                 cmp     byte ptr [ecx], 0
.text:004D25F3                 jz      loc_4D267B
.text:004D25F9
.text:004D25F9 loc_4D25F9:                             ; CODE XREF: WinMain(x,x,x,x)+44j
.text:004D25F9                 mov     al, [ecx]
.text:004D25FB                 cmp     al, 9
.text:004D25FD                 jz      short loc_4D2603
.text:004D25FF                 cmp     al, ' '
.text:004D2601                 jnz     short loc_4D2606
.text:004D2603
.text:004D2603 loc_4D2603:                             ; CODE XREF: WinMain(x,x,x,x)+3Dj
.text:004D2603                 inc     ecx
.text:004D2604                 jmp     short loc_4D25F9
.text:004D2606 ; ---------------------------------------------------------------------------
.text:004D2606
.text:004D2606 loc_4D2606:                             ; CODE XREF: WinMain(x,x,x,x)+41j
.text:004D2606                 mov     al, [ecx]
.text:004D2608                 test    al, al
.text:004D260A                 jz      short loc_4D25F0
.text:004D260C                 cmp     al, '"'
.text:004D260E                 jnz     short loc_4D2642
.text:004D2610                 inc     ecx
.text:004D2611                 xor     eax, eax
.text:004D2613                 mov     ax, CounterArgs
.text:004D2619                 inc     CounterArgs
.text:004D2620                 mov     ArgsArray[eax*4], ecx
.text:004D2627                 cmp     byte ptr [ecx], 0
.text:004D262A                 jz      short loc_4D2637
.text:004D262C
.text:004D262C loc_4D262C:                             ; CODE XREF: WinMain(x,x,x,x)+75j
.text:004D262C                 cmp     byte ptr [ecx], '"'
.text:004D262F                 jz      short loc_4D263C
.text:004D2631                 inc     ecx
.text:004D2632                 cmp     byte ptr [ecx], 0
.text:004D2635                 jnz     short loc_4D262C
.text:004D2637
.text:004D2637 loc_4D2637:                             ; CODE XREF: WinMain(x,x,x,x)+6Aj
.text:004D2637                 cmp     byte ptr [ecx], '"'
.text:004D263A                 jnz     short loc_4D25F0
.text:004D263C
.text:004D263C loc_4D263C:                             ; CODE XREF: WinMain(x,x,x,x)+6Fj
.text:004D263C                 mov     byte ptr [ecx], 0
.text:004D263F                 inc     ecx
.text:004D2640                 jmp     short loc_4D25F0
.text:004D2642 ; ---------------------------------------------------------------------------
.text:004D2642
.text:004D2642 loc_4D2642:                             ; CODE XREF: WinMain(x,x,x,x)+4Ej
.text:004D2642                 xor     eax, eax
.text:004D2644                 mov     ax, CounterArgs
.text:004D264A                 inc     CounterArgs
.text:004D2651                 mov     ArgsArray[eax*4], ecx
.text:004D2658                 cmp     byte ptr [ecx], 0
.text:004D265B                 jz      short loc_4D25F0
.text:004D265D
.text:004D265D loc_4D265D:                             ; CODE XREF: WinMain(x,x,x,x)+ABj
.text:004D265D                 mov     al, [ecx]
.text:004D265F                 cmp     al, 9
.text:004D2661                 jz      short loc_4D266D
.text:004D2663                 cmp     al, ' '
.text:004D2665                 jz      short loc_4D266D
.text:004D2667                 inc     ecx
.text:004D2668                 cmp     byte ptr [ecx], 0
.text:004D266B                 jnz     short loc_4D265D
.text:004D266D
.text:004D266D loc_4D266D:                             ; CODE XREF: WinMain(x,x,x,x)+A1j
.text:004D266D                                         ; WinMain(x,x,x,x)+A5j
.text:004D266D                 cmp     byte ptr [ecx], 0
.text:004D2670                 jz      short loc_4D267B
.text:004D2672                 mov     byte ptr [ecx], 0
.text:004D2675                 inc     ecx
.text:004D2676                 jmp     loc_4D25F0
.text:004D267B ; ---------------------------------------------------------------------------
.text:004D267B
.text:004D267B loc_4D267B:                             ; CODE XREF: WinMain(x,x,x,x)+33j
.text:004D267B                                         ; WinMain(x,x,x,x)+B0j
.text:004D267B                 mov     ax, CounterArgs
.text:004D2681                 push    offset ArgsArray
.text:004D2686                 push    eax
.text:004D2687                 call    sub_43D440
.text:004D268C                 add     esp, 8

-----------------------
.text:0043D440 sub_43D440      proc near               ; CODE XREF: WinMain(x,x,x,x)+C7p
.text:0043D440
.text:0043D440 var_165         = byte ptr -165h
.text:0043D440 var_164         = byte ptr -164h
.text:0043D440 var_144         = byte ptr -144h
.text:0043D440 var_124         = dword ptr -124h
.text:0043D440 var_104         = dword ptr -104h
.text:0043D440 CounterArgs     = dword ptr  4
.text:0043D440 ArgsArray       = dword ptr  8
.text:0043D440
.text:0043D440                 sub     esp, 168h
.text:0043D446                 push    ebx
.text:0043D447                 push    esi
.text:0043D448                 push    edi
.text:0043D449                 mov     ebx, 0FFFFFFFFh
.text:0043D44E                 push    ebp
.text:0043D44F                 mov     edi, offset aDungeonKeeper ; "Dungeon Keeper"
.text:0043D454                 mov     ecx, ebx
.text:0043D456                 sub     eax, eax
.text:0043D458                 repne scasb
.text:0043D45A                 not     ecx
.text:0043D45C                 sub     edi, ecx
.text:0043D45E                 mov     eax, ecx
.text:0043D460                 shr     ecx, 2
.text:0043D463                 mov     esi, edi
.text:0043D465                 mov     edi, offset aBullfrogShell ; "Bullfrog Shell"
.text:0043D46A                 rep movsd
.text:0043D46C                 mov     ecx, eax
.text:0043D46E                 push    6Eh
.text:0043D470                 and     ecx, 3
.text:0043D473                 rep movsb
.text:0043D475                 call    sub_4D2000
.text:0043D47A                 add     esp, 4
.text:0043D47D                 call    timeGetTime
.text:0043D482                 push    eax             ; unsigned int
.text:0043D483                 call    _srand
.text:0043D488                 mov     ecx, [esp+17Ch+ArgsArray]
.text:0043D48F                 add     esp, 4
.text:0043D492                 mov     dword_509848, 0
.text:0043D49C                 mov     edi, [ecx]
.text:0043D49E                 sub     eax, eax
.text:0043D4A0                 mov     [esp+178h+var_165], 0
.text:0043D4A5                 mov     ecx, ebx
.text:0043D4A7                 repne scasb
.text:0043D4A9                 not     ecx
.text:0043D4AB                 sub     edi, ecx
.text:0043D4AD                 mov     eax, ecx
.text:0043D4AF                 shr     ecx, 2
.text:0043D4B2                 mov     esi, edi
.text:0043D4B4                 lea     edi, [esp+178h+var_104]
.text:0043D4B8                 rep movsd
.text:0043D4BA                 mov     ecx, eax
.text:0043D4BC                 and     ecx, 3
.text:0043D4BF                 rep movsb
.text:0043D4C1                 lea     ecx, [esp+178h+var_104]
.text:0043D4C5                 push    ecx
.text:0043D4C6                 push    offset byte_552150
.text:0043D4CB                 call    _sprintf
.text:0043D4D0                 add     esp, 8
.text:0043D4D3                 push    '\'                
.text:0043D4D5                 push    offset byte_552150 ; char *
.text:0043D4DA                 call    _strrchr
.text:0043D4DF                 add     esp, 8
.text:0043D4E2                 mov     byte ptr [eax], 0
.text:0043D4E5                 push    1
.text:0043D4E7                 push    0
.text:0043D4E9                 push    0
.text:0043D4EB                 call    sub_4CDFB0








More information about the wine-devel mailing list