NO

Author Topic: Cruel World  (Read 9275 times)

czerny

  • Guest
Cruel World
« on: May 03, 2014, 03:38:34 PM »
In the following site http://www.unix.com/programming/37678-c-brain-teaser.html is the following brainteaser:

Write a C program to do a small task(lets say just simply printing a "Hello World" or so) such that the program should only give output or the desired result only once after it got compiled and should never give the output nor do anything else. The program should not make use of files or any extrnal means of storing some data.

One of the solutions presented at that site is:

Code: [Select]
#include <stdio.h>
#include <io.h>

int main (int argc, char* argv[])
{
    printf ("Bye Bye Cruel World :-( \n");
    return (_unlink (argv[0]));
}

but this does not work neither in a windows environment nor in many unix environments.

What are other solutions?

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Cruel World
« Reply #1 on: May 03, 2014, 04:24:52 PM »
Hi Czerny,
It doesn't work because trying to delete the executable from inside it causes an access fault because the file is locked while it is executing.
I have seen the solution somewhere when I'll remember I'll tell you. But is something complicated as to inject code to a different process to delete file after the locking by OS has been removed, or something the like...

Start looking here, or here.
« Last Edit: May 03, 2014, 04:30:56 PM by frankie »
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: Cruel World
« Reply #2 on: May 03, 2014, 09:22:35 PM »
One nasty trick (on 32-bit OS only) is to write a few bytes to disk containing a 16-bit DOS exe which kills the 32-bit parent process and then itself.

This works fine in assembler:

  CASE WM_DESTROY
   invoke PostQuitMessage, NULL
   Launch Cat$("cmd.exe /c del "+CL$(0)), SW_HIDE, 1  ; timeout 1 ms

... but no success with what seems to me the C equivalent:

   case WM_DESTROY:
      {
      char buffer[300];   // MAX_PATH+15, ca.
      lstrcpy(buffer, "cmd.exe /c del ");
      GetModuleFileName(0, buffer+15, 285);
      // MessageBox(0, buffer, 0, MB_OK);
      PostQuitMessage(0);
      system(buffer);
      }


GOTCHA!! Forget system...

   case WM_DESTROY:
      {
      char buffer[300];   // MAX_PATH+15, ca.
      lstrcpy(buffer, "cmd.exe /c del ");
      GetModuleFileName(0, buffer+15, 285);
      PostQuitMessage(0);
      WinExec(buffer, SW_HIDE);
      }
« Last Edit: May 04, 2014, 01:28:34 AM by jj2007 »

Offline Bitbeisser

  • Global Moderator
  • Member
  • *****
  • Posts: 772
Re: Cruel World
« Reply #3 on: May 04, 2014, 01:52:57 AM »
One nasty trick (on 32-bit OS only) is to write a few bytes to disk containing a 16-bit DOS exe which kills the 32-bit parent process and then itself.

This works fine in assembler:<snip>
Maybe, but it is against the requirements of the task:
Quote
The program should not make use of files or any extrnal means of storing some data.
Ralf

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: Cruel World
« Reply #4 on: May 04, 2014, 04:07:32 AM »
Maybe, but it is against the requirements of the task:
Quote
The program should not make use of files or any extrnal means of storing some data.
Ralf

The part below "GOTCHA" fits the requirement of the task.

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: Cruel World
« Reply #5 on: May 04, 2014, 07:22:04 AM »
Nice, it works.
Code: [Select]
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

void KillMe(void)
{
    char szBuf[260+11] = "cmd /c del ";
    GetModuleFileName(0, &szBuf[11], 260);
    WinExec(szBuf, SW_HIDE);
}

int main(int argc, char **argv)
{
    KillMe();
    return 0;
}
« Last Edit: May 04, 2014, 07:54:23 AM by TimoVJL »
May the source be with you

czerny

  • Guest
Re: Cruel World
« Reply #6 on: May 04, 2014, 04:26:09 PM »
Code: [Select]
    KillMe();
Sleep(20); // works
Sleep(30); // doesn't work
    return 0;
There is not much time, not enough for a gui programm, I guess.
But that was not the challenge.

czerny

  • Guest
Re: Cruel World
« Reply #7 on: May 04, 2014, 04:45:48 PM »
Here is an article about self-deleting exes: http://www.catch22.net/tuts/self-deleting-executables

But there should exist other ways (without deleting the exe) eventually!

Self-modifying code shouldn' be possible in this case? Or is it still possible?

Don't know, if the following solutions are not against the rules:
- use exe's creation time, last access time difference
- use the exe's attrib-flag as work/work not flag

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: Cruel World
« Reply #8 on: May 04, 2014, 07:42:54 PM »
There is not much time, not enough for a gui programm, I guess.

There is plenty of time. This works on my slow old machine.

   case WM_DESTROY:
      {
      char buffer[300];   // MAX_PATH+15, ca.
      lstrcpy(buffer, "cmd.exe /c del ");
      GetModuleFileName(0, buffer+15, 285);
      PostQuitMessage(0);
      WinExec(buffer, SW_HIDE);
      Sleep(30);  // just for fun
      }

czerny

  • Guest
Re: Cruel World
« Reply #9 on: May 04, 2014, 08:21:01 PM »
This works on my slow old machine.
There is always a slower machine. ;)

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: Cruel World
« Reply #10 on: May 04, 2014, 08:30:46 PM »
How slow ?
Code: [Select]
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
...
KillMe();
return msg.wParam;
}
May the source be with you