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@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