cdebuggingwinapilcc-win32

LCC-- How to stop debugger from breaking at the start of the application?


I'm not sure of how many users there are out there that use the LCC C compiler and the WEdit GUI for Windows but it has a "feature" that is can get to be quite annoying. When you start an application with the debugger, it breaks the application at the start of the Main function. How can I cut this off so that the debugger immediately executes the code until I halt it or it hits a break point that I've created?


Solution

  • Wow, people still use LCC... Last time I used it was ~10 years ago.

    I decompiled wedit.exe and can confirm there is no official way to disable this behavior.

    I patched the binary if that works for you. I uploaded it here.

    To those who concerned about viruses and such I patched wedit taken from here. About box says it's version 4.0 compiled at Sep 16 2009.

    Here is patched function to those who interested:

    int __cdecl sub_44CF0D(HANDLE hProcess)
    {
      int result; // eax@1
      int v2; // ST0C_4@10
      int v3; // eax@20
      int v4; // eax@23
      int v5; // eax@25
      int v6; // [sp+10h] [bp-68h]@11
      int v7; // [sp+14h] [bp-64h]@1
      struct _DEBUG_EVENT DebugEvent; // [sp+18h] [bp-60h]@1
    
      v7 = 1;
      result = WaitForDebugEvent(&DebugEvent, dwMilliseconds);
      if ( result )
      {
        sub_44C67A(&DebugEvent);
        if ( DebugEvent.dwDebugEventCode == 1 )
        {
          if ( DebugEvent.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_ACCESS_VIOLATION
            && !(dword_482860 & 1)
            && !dword_484328
            && DebugEvent.u.Exception.dwFirstChance )
          {
            sub_44E1A5(0);
            sub_44CEB2(v2);
            return ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, 0x80010001u);
          }
          v6 = 0;
          v7 = sub_44D2C4((int)&DebugEvent, hProcess, (int)&v6);
          if ( v6 && DebugEvent.u.Exception.dwFirstChance )
            return ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, 0x80010001u);
          goto LABEL_41;
        }
        if ( DebugEvent.dwDebugEventCode == 3 )
        {
          if ( dword_483C94 )
          {
            dword_48428C = 1;
    LABEL_41:
            if ( dword_483C6C )
              sub_44ECDC();
            if ( v7 )
            {
              result = ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, 0x10002u);
            }
            else
            {
              dword_49BF68 = 1;
              ResetEvent(dword_484AE4);
              dword_4843C8 = DebugEvent.dwThreadId;
              result = sub_4524CD();
            }
            return result;
          }
          Sleep(0x32u);
          dword_49BF64 = 1;
          dword_49BF68 = 1;
          qword_483C74 = __PAIR__(
                           (unsigned int)DebugEvent.u.Exception.ExceptionRecord.ExceptionAddress,
                           DebugEvent.u.Exception.ExceptionRecord.ExceptionInformation[2]);
          if ( dword_484288 )
            ::hProcess = (HANDLE)DebugEvent.u.Exception.ExceptionRecord.ExceptionFlags;
          else
            ::hProcess = hProcess;
          dword_483C84 = DebugEvent.dwProcessId;
          hThread = DebugEvent.u.Exception.ExceptionRecord.ExceptionRecord;
          dword_483C9C = (HANDLE)DebugEvent.u.Exception.ExceptionRecord.ExceptionCode;
          dwThreadId = DebugEvent.dwThreadId;
          dword_483C94 = 0;
          if ( sub_45A83A() )
          {
            v4 = sub_4026A6(28);
            dword_484330 = v4;
            *(_DWORD *)(v4 + 4) = hThread;
            *(_DWORD *)(v4 + 8) = dwThreadId;
            if ( dword_484288 )
            {
              sub_455B58();
            }
            else
            {
              Sleep(0x64u);
              v5 = sub_45AAFC();
              if ( !v5 )
                return PostMessageA(dword_4849EC, 0x111u, 0x64u, 0);
              if ( dword_484354 )
                goto LABEL_50;
              sub_455B58();
              if ( dword_483C70 && *(_DWORD *)(dword_483C70 + 52) )
                *(_DWORD *)(*(_DWORD *)(dword_483C70 + 52) + 36) = sub_451577(**(_DWORD **)(dword_483C70 + 52), 1u);
              v5 = *(_DWORD *)(dword_483C70 + 52);
              if ( v5 && *(_DWORD *)(v5 + 36) )
              {
    LABEL_50:
                if ( !dword_483C6C )
                  sub_44E92A(v5);
                sub_44CC3D();
                sub_451600();
                PostMessageA(dword_4849EC, 0x111u, 0x154u, 0);
              }
              else
              {
                sub_4029CA("Imposible to find %s\nRunning without source display", *(_DWORD *)(dword_483C70 + 20));
                dword_484344 = 1;
                v7 = 1;
                PostMessageA(dword_4849EC, 0x111u, 0x154u, 0);
              }
            }
            goto LABEL_41;
          }
          dword_484338 = 1;
          v3 = sub_44DB56(qword_483C74);
          if ( v3 )
            *(_BYTE *)(v3 + 29) &= 0xFDu;
          result = ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, 0x10002u);
        }
        else
        {
          if ( DebugEvent.dwDebugEventCode != 5 )
            goto LABEL_41;
          if ( DebugEvent.dwProcessId != dword_483C84 )
          {
            v7 = 1;
            goto LABEL_41;
          }
          dword_49BF64 = 0;
          dword_49BF68 = 1;
          dword_481614 = 0;
          result = sub_402A32(4520, SLOBYTE(DebugEvent.u.Exception.ExceptionRecord.ExceptionCode));
          if ( !dword_483C6C )
            result = sub_40B155(lpCmdLine);
        }
      }
      else
      {
        if ( dword_483C6C )
          result = sub_44ECDC();
      }
      return result;
    }
    

    if under LABEL_50 is what I patched (from 0x75 to 0xEB).

    It was easy to spot the place because I expected WriteProcessMemory to be used to write 0xCC at entry-point of application that is being debugged.