Lex Posted August 8, 2007 Share Posted August 8, 2007 Hi again guys ! I've read on a website this following programming challenge ( for a job interview ) : -you are supposed to write an application which should display a string ( whatever you want , say "string 1" ) the first time it's being ran , and a different string ( say "string 2") if you run it again . However , you are not allowed to create write to additional files , or to the registry . I've solved this challenge in perl using the following code : use Tie::File; tie my @array,'Tie::File',$0 || die "Tie errorn"; my $tmf; chomp($tmf=<DATA>); if($tmf eq "string1") { print "First runn"; for(my $i=0;$i<$#array+1;$i++) { if($array[$i] eq "string1") { ($array[$i],$array[$i+1])=($array[$i+1],$array[$i]); last; } } untie @array; } else { print "Not first runn"; } __DATA__ string1 string2 The code runs on any platform that supports perl . I tried to solve it in C too , but I've only got it to work under Linux ( the way I did it was using exec , replacing the current process image with another image that writes data in the file ) ... but on Windows the C code crashes . I would love to see another solutions for this challenge . Cheers ! Quote Link to comment Share on other sites More sharing options...
natural_orange Posted August 8, 2007 Share Posted August 8, 2007 I don't understand..... could you please explain this again in more detail.... Quote Link to comment Share on other sites More sharing options...
Lex Posted August 8, 2007 Author Share Posted August 8, 2007 I don't know how to make this any clearer ... when you first run it , it should write "string 1" to the console ; and if you run it again , it should display "string 2". Quote Link to comment Share on other sites More sharing options...
cooper Posted August 9, 2007 Share Posted August 9, 2007 I had to look this over a couple of times before I got the idea. What you're asked to do is to rewrite the program from within the program, as the program itself is the only file on the system that you're allowed to edit. In C I think the best way to do it is to put the string to replace in a global constant. You first print out that constant, and then do a replace on the file contents for the string with a new version of that string. Note that the new string must be the same length as the original. There might be other ways to do it, but I reckon that unless you want to figure out how each compiler puts together its local binary, it's not worth the effort. Quote Link to comment Share on other sites More sharing options...
jollyrancher82 Posted August 9, 2007 Share Posted August 9, 2007 I get that the idea is to have the program output a string of your choice every time the program is run but the string must be unique? I would solve this by, outputting the epochs timestamp, then sleeping for 1 second. The output would be unique everytime, because the sleep stops the person running the program quickly. That's the hackers way :D Quote Link to comment Share on other sites More sharing options...
Lex Posted August 9, 2007 Author Share Posted August 9, 2007 Tom , the first time you run the program , it should display a string , and after that , it doesn't matter how many times you run it again , it will display a second string ... kinda like the app knows if it's the first time being ran or not . Quote Link to comment Share on other sites More sharing options...
mexxus Posted August 9, 2007 Share Posted August 9, 2007 Hey, I know theres a way to do it in C#, but haven't looked into it enough. Theres a way of adding global variables within the application that are embedded within the compiled executable. So it will read the variables containing the 2 string values and the number of times the program has been open. At first the program would read the first string, and obviously when the count reaches 2, it would display the second string. mexxus Quote Link to comment Share on other sites More sharing options...
Lex Posted August 9, 2007 Author Share Posted August 9, 2007 It would be nice if you could show us some code :) Quote Link to comment Share on other sites More sharing options...
natural_orange Posted August 9, 2007 Share Posted August 9, 2007 that is neat, i didn't really understand it the first time Quote Link to comment Share on other sites More sharing options...
mexxus Posted August 10, 2007 Share Posted August 10, 2007 Hey, I did some searching in msdn, and have found out how to do it. It doesn't seem to use any external sources to store data, but not entirely sure. The only problem is... I have attached a reset button, but it only resets the second time you open the program after clicking reset...strange. Hmmmm...how to upload? I'll start work on a ftp server etc etc. go to http://www.nuckingfoobs.com/files (doesn't exist at the moment, but will purchase soon and host domain) The file will be variable_container.zip or similar. mexxus Quote Link to comment Share on other sites More sharing options...
Lex Posted August 10, 2007 Author Share Posted August 10, 2007 Link not working Quote Link to comment Share on other sites More sharing options...
brainfreeze Posted August 10, 2007 Share Posted August 10, 2007 I think this is what you ment. "you are not allowed to create write to additionalfiles , or to the registry . But you can write to yourself (the program) right? Thats not breaking the rules is it? A program that re-programs itself. If its not breaking the rules, then here is a solution in php. hak5.php <?php $cent = "false"; if($cent == "false") { echo "string 1"; $lines = file('hak5.php'); $myFile = "hak5.php"; $fh = fopen($myFile, 'w') or die("can't open file"); $i = 0; foreach ($lines as $line) { $i += 1; } $lines[1] = '$cent = "true";'; for ( $counter = 0; $counter <= $i; $counter +=1) { fwrite($fh, $lines[$counter]); } } if($cent == "true") { echo "string 2"; // two coins add up too 21cent // one of them isn't 1cent // thats what this challenge reminds me of! :) // sorry for the bad code - im sure it can be done in alot less lines. } ?> After this is executed, it will never return to display "string 1", as the second line in the code has been changed to 'true'. It can only revert back to "string 1" is someone opens the source up with a text editor and changes it back. Quote Link to comment Share on other sites More sharing options...
Lex Posted August 10, 2007 Author Share Posted August 10, 2007 You got it! Quote Link to comment Share on other sites More sharing options...
brainfreeze Posted August 10, 2007 Share Posted August 10, 2007 sweet :) Quote Link to comment Share on other sites More sharing options...
Maikeru Jirushisu Posted August 27, 2007 Share Posted August 27, 2007 Hypothetically, couldn't one hard-code the approximate size of the application into the application, and have it add some empty bits to the end of it after it's first run. It could check it's own size and display a different output if it finds itself significantly bloated. Just a similar but different means. Quote Link to comment Share on other sites More sharing options...
jollyrancher82 Posted August 27, 2007 Share Posted August 27, 2007 I'd like to see this done using a compiled language, instead of an interpreted one. Quote Link to comment Share on other sites More sharing options...
cooper Posted August 27, 2007 Share Posted August 27, 2007 I tried it with a little C program, but (at least under Linux) you can't open your own binary from within your program. The open(2) call fails when the flag is O_WRONLY, saying that the file is busy (ETXTBSY). You can cheat though: #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <string.h> const char *txt1 = "A certain text."; const char *txt2 = "A similar text."; static void die(char *reason) { printf("%sn",reason); exit(-1); } static off_t get_file_size(const char *filename) { struct stat file_stat; if (stat(filename, &file_stat) != 0) { die("Error statting file, and too lazy to write a real error."); } return file_stat.st_size; } static void replace_in_buffer(const char *old,const char *new,char *buffer,off_t buffer_size) { size_t old_len = strlen(old); char *cur_pos = buffer; char *end_pos = buffer + buffer_size - old_len; while (cur_pos < end_pos) { if (memcmp(old,cur_pos,old_len) == 0) { memcpy(cur_pos,new,old_len); printf("Buffer patched.n"); break; } cur_pos++; } return; } static void read_file_contents(const char *filename, char *buffer,off_t buffer_size) { int fd; if ( (fd = open(filename,O_RDONLY)) < 0) { die("Unable to open called binary for read access."); } if (read(fd,buffer,buffer_size) != buffer_size) { die("Amount of bytes read less than expected."); } close(fd); } static void write_file_contents(const char *filename,char *buffer, off_t buffer_size) { int fd; if (unlink(filename) != 0) { /* Yup, this is cheating. */ die("Unable to remove the original program."); } if ( (fd = open(filename,O_CREAT|O_WRONLY)) < 0) { die("Unable to open called binary for write access."); } if (write(fd,buffer,buffer_size) != buffer_size) { die("Amount of bytes written less than expected - expect a corrupt binary."); } close(fd); } int main(int argc, char *argv[]) { const char *filename = argv[0]; off_t filesize; char *buffer; filesize = get_file_size(filename); if ( (buffer = malloc(filesize)) == NULL) { die("Unable to allocate memory buffer."); } read_file_contents(filename,buffer,filesize); replace_in_buffer(txt1,txt2,buffer,filesize); write_file_contents(filename,buffer,filesize); free(buffer); printf("Text1: %snText2: %sn",txt1,txt2); return 0; } Um. Suffice to say that this works because the two strings are of equal length. I'm pretty sure if they weren't, Bad Things would happen. Quote Link to comment Share on other sites More sharing options...
jollyrancher82 Posted August 28, 2007 Share Posted August 28, 2007 I am thinking of a sneaky-smart-ass way to do it on Windows, but the rules of the challenge need to be made clear before I tell people my way. I'll update this post with my source code in a minute. Quote Link to comment Share on other sites More sharing options...
Dargor Posted August 29, 2007 Share Posted August 29, 2007 Heres my way in python. you are not allowed to create write to ADDITIONAL files ok, just write to the app file. might not be able to do this in those silly need-to-compile languages. #!/usr/bin/python string1 = "this is the first string" string2 = "this is the second stirng" run = 1 if run == 1: print string1 elif run == 2: print string2 f=open('app.py', 'r+') # open self, if self named app.py f.seek(101) # go to the (run = 1) line f.write('2') # write 2 over the 1 Quote Link to comment Share on other sites More sharing options...
brainfreeze Posted August 31, 2007 Share Posted August 31, 2007 I'd like to see this done using a compiled language, instead of an interpreted one. I second that. Although my code in php wasn't cheating, doing it with a compiled language would be alot more impressive. Just to show it can be done. Quote Link to comment Share on other sites More sharing options...
SomeoneE1se Posted August 31, 2007 Share Posted August 31, 2007 I'd like to see this done using a compiled language, instead of an interpreted one. I second that. Although my code in php wasn't cheating, doing it with a compiled language would be alot more impressive. Just to show it can be done. /me waits for TomB Quote Link to comment Share on other sites More sharing options...
Lex Posted September 1, 2007 Author Share Posted September 1, 2007 I've done it in C too ... I'll search for the code and i'll post it here . I had it exec another program that appended some data to the original binary , thus changing its size . It worked only on Linux Quote Link to comment Share on other sites More sharing options...
cooper Posted September 2, 2007 Share Posted September 2, 2007 I'd be quite interested in seeing that. Appending data to a binary sounds like... tricky stuff. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.