vortex level10

2011. 4. 18. 06:35


Vortex Level10에 대한 설명입니다.

Random?
          Read in 20 integers and write the seed used to generate those numbers in unsigned little endian format. You have a time limit of 30 seconds to do this.


"20개의 정수를 읽고 이 정수값을 생성하는 seed를 30초 안에 써라" 라고 하네요.

파일을 실행한 결과는  다음과 같습니다.



IDA F5 신공으로 보면,

   v1 = times(&buffer);

    tmp = buffer.tms_cstime + buffer.tms_cutime + buffer.tms_utime + buffer.tms_stime + v1;

    tmp += clock();
    tmp += time(0);

    num = tmp;

    if ( tmp < 0 ) {
        num = tmp + 255;
    }

    tmp = 128 - (tmp - (num >> 8 << 8));

    seed = tmp + time(0);

seed 를 생성하는 루틴에서 사용하는 함수들은 다음과 같습니다.

1) times function.

NAME
       times - get process times

SYNOPSIS
       #include <sys/times.h>

       clock_t times(struct tms *buf);

DESCRIPTION
       times()  stores  the  current process times in the struct tms that buf points to.  The struct tms is as defined in <sys/times.h>:

           struct tms {
               clock_t tms_utime;  /* user time */
               clock_t tms_stime;  /* system time */
               clock_t tms_cutime; /* user time of children */
               clock_t tms_cstime; /* system time of children */
           };

   times() 함수는 현재 프로세스 타임을 tms구조체에 되돌려줍니다.

     tms_utime는 프로세스가 호출한 명령을 수행하기 위해서 소비된 시간이다.
     tms_stime는 프로세스의 명령을 시스템차원에서 실행하는데 소비된 시간이다.
     tms_cutime은 종료된 모든 자식프로세스가 소비한 tms_utime이다.
     tms_cstime은 종료된 모든 자식프로세스가 소비한 tms_stime이다.

2) clock() function  - 프로그램이 실행된 후 경과한 Clock Tick을 반환

To get a process' CPU time, you can use the clock function. This facility is declared in the header file time.h. In typical usage, you call the clock function at the beginning and end of the interval you want to time, subtract the values, and then divide by CLOCKS_PER_SEC (the number of clock ticks per second) to get processor time, like this:

 #include <time.h>         
 clock_t start, end;    
 double cpu_time_used;         
 start = clock();     ... /* Do the work. */    
 end = clock();    
 cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;

3) time() function
http://www.joinc.co.kr/modules/moniwiki/wiki.php/article/unixtime

1970년 1월 1일(GMT)를 기준으로 지금까지 흐른 시간을 초 단위로 측정

위의 함수들을 조합해서 seed를 생성한 후에 rand() 함수로 값을 찍습니다.
이 루틴을 그대로 이용해서 level10으로  넘기면 될거 같네요.

처음엔 파일로 쓴 후에 읽게 했습니다. Local system 인 ubuntu 에서는 성공했지만
이 느려터진 vortex 시스템에선 계속 "None, try again" 만 뜨더군요.

파일로 쓰는 시간을 줄일 수 없을까 하다,  Pipe 를 이용해서 해결했습니다.
이 문제를 푼게 올해 초라서.. 지금 다시 돌려보니 깔끔하게 떨어지진 않네요 흑..
사용되는 연산이 적으면 아무래도 시스템 성능에 영향을 더 받겠죠?
File, Pipe 이외에 더 적은 연산을 수행하는 방법이 없을까요.

풀이에 사용한 코드 입니다.


 
#include <stdio.h>
#include <sys/times.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#define LEVEL10 "/vortex/level10"

int main(void) 
{
    struct          tms buffer;
    clock_t         v1;
    int             num,tmp,i,j,pid;
    unsigned int    seed;
    int             buf[22] = {0}; 
    char            result[16] = {0};
    char            last[16] = {0}; 
    int             p[2] = {0};
    char            temp[4] = {0};
    char            response[256] = {0};
    //char            action[] = "ls -al > /tmp/result\n";
    char            action[] = "cat /etc/vortex_pass/vortex11 > /tmp/result\n";
    char            end[] = {0};

    v1 = times(&buffer);

    tmp = buffer.tms_cstime + buffer.tms_cutime + buffer.tms_utime + buffer.tms_stime + v1;

    tmp += clock();
    tmp += time(0);

    num = tmp;

    if ( tmp < 0 ) {
        num = tmp + 255;
    }

    tmp = 128 - (tmp - (num >> 8 << 8));

    seed = tmp + time(0);
    printf("seed : %d\n", seed);
    sprintf(result,"%x",seed);

    j=3;

    for (i=0;i<strlen(result); i=i+2) 
    {
        sprintf(temp,"%c%c",result[i],result[i+1]);
        last[j] = strtol(temp,NULL,16);
        j--;
     }
if 1
    srand(seed);

    setvbuf(stdout, 0, 2,0);

    for ( i = 0; i < tmp; ++i) {
        rand();
    }

    printf("[");
    for ( i = 0; i <= 19; ++i) {
        buf[i] = rand();
        printf(" %08x,", buf[i]);
    }

    printf("]\n");
#endif

    pipe(p);

    if((pid =fork()) == 0)
    {
        dup2(p[0],0);
        close(p[1]);
        execl("./level10","level10",NULL);
    }
    else
    {
        close(p[0]);
        write(p[1], last, strlen(last));
    }

    write(p[1], action, sizeof(action));
    sleep(1);
    write(p[1], end, sizeof(end));

    return 0;
}

'War game > vortex' 카테고리의 다른 글

vortex12  (0) 2014.01.02
Vortex11  (3) 2013.04.02
vortex level8  (0) 2010.12.09
vortex level3  (0) 2009.10.03
vortex level1  (0) 2009.09.24
vortex level0  (0) 2009.09.23

badcob War game/vortex