쓰레기 코드

 | C, C++
2008/11/29 15:41

쓰레기 코드




프로텍터나 패커류는 안티디버깅을 위하여 쓰레기 코드를 많이 삽입하죠.
그리고 요즘엔 굳이 그런 부류가 아니더라도 안티 리버싱이 필요한 일반 프로그램에도
쓰레기 코드를 넣을 때가 종종 있습니다.

보통 쓰레기 코드는 이런 스타일이죠.



이 코드가 돌아가면, 결론적으로는 아무 짓도 안한게 되죠 ㅎㅎ
지금의 코드는 단순히 4줄이라 머 대충 띡 봐도 아 ㅅㅂ 더미 코드구나.. 하는 생각이 들지만
릴리즈 모듈에서 이런게 진짜 코드 사이사이에 와장창 끼어있다면 공격하는 해커 입장에선
참 짜증이 나죠 :p

즉, 이것이 바로 해커를 혼란스럽게 하기 위한 스레기 코드 삽입입니다.

그런데 실제로 상용 모듈을 만들다보면, 졸면서 코딩하든 일에 쫓겨서 급 코딩하든
위 목적과는 당연히 아무 상관없고 본의 아니게 추가된 쓰레기 코드가 들어가게 됩니다.
예를 들면요,



초딩이 짠 코드도 아니고.....겁나 욱기죠...ㅋ
한술 더떠서 이런 코드도 나옵니다.




설마 상용 소프트웨어에 저런 짓을 해놨겠습니까... 라고 반문하실 수 있겠지만
네.. 실제로 저런 코드가 릴리즈 버전에도 여기저기 널부러져 있는 경우가 많습니다...lol
코드가 수만 수십만줄이 넘고, 하루하루 전쟁같은 유지보수와 수정 작업에 시달리다 보면
저런 코드가 안나올 수가 없습니다 :)

또 현업 개발자들은 많은 경험과 높은 연륜으로 무장하신 분들인데 저러겠느냐 라고 생각되겠지만
실제로 업무를 해 보면 메이저급 회사가 아닌 경우 대부분의 개발 환경은 매우 열악하고
몇명의 개발자들의 1인 다역을 하며 수퍼맨처럼 일하고 있죠.
그래서 코딩 완료후 개발자들끼리 모여 코드 리뷰? 이런건 꿈에 불과한 이야기입니다
개발자를 우대하는 몇몇 회사에서는 그런 코드 리뷰 프로세스도 있다고 들었지만
대부분 고객들의 아우성에 똥줄 타면서 급박하게 모듈을 내놓느라 그런 시간을 가질래야
가지기가 힘든 실정입니다... :(

또 저런 코드가 발견되어도... "아 ㅅㅂ 저따위로 해놨냐... 머 잘돌아가고 있으니까 걍 냅둬"
라는 인식을 가진 사람들도 있어서 (괜히 건드렸다가 문제 생기는거 시러하는 사람들)
저런 사태는 알아차려도 잘 고치려 하지 않죠 ㅋ

또, 요즘 똑똑한 컴파일러들은 개발자들의 저런 ㅄ짓을 빌드 단에서 제외해 주기도 하니까요.
하지만 어쨌든 후임이나 동료 개발자가 저런 소스를 인계 받았을 때 눈이 뒤집히는건 사실입니다 ㅎ

어쨌든 스레기 코드는 해커들을 혼란스럽게 하기 위한 목적으로 추가되는 것들입니다.
하지만 이런 쓰레기 코드는 개발팀 동료들을 혼란스럽게 합니다 ;;
그러다보니 그런 생각도 들어요... 쓰레기 코드를 아주 습관적으로 만들어내는 개발자들은
차라리 프로텍터나 패커를 만들게 하자... 괜히 억지로 더미 코드 만들라고 강요 안해도
평소 코딩 스타일로도 아주 잘만들듯 :)

친구랑 스레기 코드에 대해 논하다가 생각난 이야기들입니다 :)


2008년 11월.
window31.

Posted by window31


트랙백 보낼 주소 : http://window31.com/trackback/225 관련글 쓰기

댓글을 달아주세요

  1. 2008/11/29 19:27
    댓글 주소 수정/삭제 댓글
    넥슨같은 좋은 회사도 일정에 쫒기나요? ㅎㅎ

    저희 팀 같은 경우는 일주일에 한두번 꼴로 코드 리뷰를 합니다. 처음에는 아주 죽을 맛이었는데, 리뷰를 할때마다 버그를 잡아내는 선배들을 보니 정신을 바짝 차려야겠다는 생각이 들더라구요. 뛰어난 팀장이 외세의 압력에 잘 버텨주는 편이라 릴리즈 직전에는 무조건 코드 리뷰를 1번 이상 합니다. ㅎㅎ

    문제는 그래도 버그가 나온다는거... ㅠㅠ)-b
    좋은 글 잘 보고 갑니다. ^^
    • 2008/12/08 00:46
      댓글 주소 수정/삭제
      반드시 요즈음의 얘기는 아니지만 ^^;
      어디가나 일정에는 늘 쫓기겠죠 ㅎㅎㅎ
      코드리뷰... 역시 S사는 좋은 회사군요 ㅠㅠ
      그래도 버그는 나온다는 말에 공감하지만
      코드리뷰를 통해 개개인이 얻을 수 있는것이 참 많으니
      반드시 필요하다고 생각합니다.
      외세의 압력을 버텨주는 팀장님이 계신것도 참 좋은것 같네요 ㅎㅎ
  2. 멍멍닷넷
    2008/11/29 20:14
    댓글 주소 수정/삭제 댓글
    쓰레기 코드 만드는 일은 참으로 곤욕이더군요.

    오히려 정상 코드보다 더 어려운 것이, 정말 순수하게 아무일도 안하고, 복잡하면서, 버그도 없으며, 소요되는 시간 조차 거의 없어야 한다는 것 ㅠㅠ

    또한, 복잡하기 위해서 반드시 디스어셈블리된 코드로 일일히 확인해야 한다는것...

    코드리뷰는 예전에 회사에서 워낙 진기한 버그들이 많은 프로젝트들을 수정하느라 몇번 신청해본적(코드 리뷰를 하고 싶으니 시간을 좀 할애해주세요) 있습니다.

    다소 떨떠름한 반응으로, 잘된다는 보장도 없는데 왜하냐 라는 느낌이더라구요. 그 이후로 아예 다음부터는 코드 리뷰라고 이야기하지 않고 그냥 디버깅하는 시간을 달라고 이야기를 합니다. 아니면 처음부터 다른 일정을 조금씩 늘려서 짜거나요.

    오히려 아예 일정에도 없으니 부담도 없고 좋더라구요. 덜덜...
    • 2008/12/08 00:48
      댓글 주소 수정/삭제
      아 완전 수긍할 수 밖에 없는 이야기만 쭈욱 써주셨네요 ㅎ
      요즘 성공하는 프로젝트에 대한 마소 연재물 잘 보고 있어요.
      실 프로젝트를 오랫동안 경험해본 사람만이 할 수 있는 내공깊은 이야기들을
      자세히 풀어주셔서 아주 흥미롭게 보고 있습니다 ㅎㅎ
  3. 2008/12/02 11:23
    댓글 주소 수정/삭제 댓글
    쓰레기코드 잘 만드는 사람.. 환영!!
  4. 2008/12/06 13:29
    댓글 주소 수정/삭제 댓글
    쓰레기 코드를 만들 때는 일반적으로 잘 알려진 수법 말고 좀 어려운 instruction을 사용해야 혼동하기 쉬울것 같네요. (제 생각입니다)

    아래와 같이 되어 있으면 리버서는 pushad~popad가 Dummy Code 영역임을 눈치채기가 쉽지만...
    pushad
    xor eax, eax
    inc ebx
    popad

    아래와 같이 약간 꼬아놔야할것 같네요...
    push esi
    push ebx
    lea esi, dword ptr ss:[ebx]
    clc
    xor [esp], esi ; [esp]=0
    jc $+1200h
    add [esp], 12345678h
    pop esi
    pop esi
    • 2008/12/08 00:51
      댓글 주소 수정/삭제
      맞습니다. 알려진 수법은 아무래도 쉽게 눈치챌수잇죠 ㅎ
      근데 아래와 같이 꼬아놓은 내용도 아쉬운것은,
      고수들은 척보면 쓰레기 코드라는 것을 안다는 겁니다 ㅠ ㅠ
      왜냐면 아무래도 실제로 저런 어셈코드가 생성될 일은 거의 없으니까요... :(
      그런 고수가 많지는 않겠지만 ㅎㅎ 어쨌든 좋은 댓글 감사드려요 !
  5. 2008/12/16 00:47
    댓글 주소 수정/삭제 댓글
    비밀댓글입니다
    • 2008/12/17 10:06
      댓글 주소 수정/삭제
      ㅇㅇㅇㅇㅇㅇ!
  6. Dual
    2008/12/16 21:13
    댓글 주소 수정/삭제 댓글
    ㅋㅋ pushad 자체를 본순간 스크롤바를 내려보게 되죠,
    popad가 있는지 보기 위해 가운데에 뭐가 있는진 보통 그다음에
    보지 않나요?ㅎㅎ 저만 그러는가...ㅠ0ㅠ
    • 2008/12/17 10:08
      댓글 주소 수정/삭제
      몇몇 옵코드를 보는 순간 대칭되는 옵코드를 찾는게 생각은 되지만 눈이 따라가지 않던데 ㅎㅎ
      하지만 사무엘군 쯤 되니 그게 될거라는 생각이 : )
    • 2008/12/17 10:55
      댓글 주소 수정/삭제
      Dual님 ~~~

      저만 그런게 아니었군요(퍼벅)^^ ㅋㅋㅋ
  7. ks
    2009/01/23 00:42
    댓글 주소 수정/삭제 댓글
    그러니까 아까 심심해서 만든 코드인데,

    #include<stdio.h>
    #include<memory.h>
    #include<malloc.h>
    #include<conio.h>
    #include<windows.h>
    #define DEEP 1000
    char bs[12]={ 0xb8,0x00,0x00,0x00,0x00,//mov eax, ?
    0xbb,0x00,0x00,0x00,0x00,//mov ebx, ?
    0xff,0xe3};//jmp ?
    char tprocs[]={0x90,0x90,0x60,0x8b,0xd8,0x83,0xe3,0x00,0x33,0xdb,0x33,0xc0,0x60,0x61,0x8b,0xc2,0x8b,0xd1,0x8b,0xd9,0x2b,0xd3,0x61,0xff,0xe0};
    /*void _declspec(naked) tproc(){ _asm{ pushad; mov ebx,eax; and ebx,0x00000000; xor ebx,ebx; xor eax,eax; pushad; popad; mov eax,edx; mov edx,ecx; mov ebx,ecx; sub edx,ebx; popad; jmp eax; }}*/
    int _stdcall tp(char *s){
    printf(s);
    return (int)s;
    }
    int makecode(void *func,char *arguments,int argubytes){
    int to=(int)func;
    char rs[DEEP][12];
    char *tproc=(char*)malloc(sizeof(tprocs));
    int i,j;
    int rsp,tpp;
    int old=0;
    memcpy(tproc,tprocs,sizeof(tprocs));
    tpp=(int)tproc;
    srand(GetTickCount());
    for(i=1;i<DEEP;i++){
    if(i%((rand()%10)+1)==0){
    for(j=0;j<12;j++){
    rs[old][j]=bs[j];
    }
    rsp=((int)rs[i]);
    memcpy(rs[old]+1,&rsp,4);
    memcpy(rs[old]+1+5,&tpp,4);
    old=i;
    }else{
    for(j=0;j<12;j++){
    rs[i][j]=rand()%0x100;
    }
    }
    }
    for(i=0;i<12;i++){
    rs[old][i]=bs[i];
    }
    memcpy(rs[old]+1+5,&tpp,4);
    tpp=(int)to;
    memcpy(rs[old]+1,&tpp,4);
    rsp=((int)(&rs[0][0]));
    unsigned int temp;
    for(i=0;i<argubytes;i+=4){
    temp=0;
    temp=(temp<<8) | (arguments[i+3]&0xff);
    temp=(temp<<8) | (arguments[i+2]&0xff);
    temp=(temp<<8) | (arguments[i+1]&0xff);
    temp=(temp<<8) | (arguments[i+0]&0xff);
    _asm{
    push temp;
    }
    }
    int retval;
    _asm{
    call rsp;
    mov retval,eax;
    }
    free(tproc);
    return retval;
    }
    void main(){
    while(1){
    printf("%c",makecode(getch,0,0));
    }
    }

    이런 코드 말이겠죠? 사실 정리하면
    #include<stdio.h>
    #include<conio.h>
    void main(){
    while(1){
    printf("%c",getch());
    }
    }
    이라는...

    원래는 패커 만들다가 귀찮아서 버렸다는...

BLOG main image
by window31

카테고리

분류 전체보기 (281)
Reverse Engineering (21)
C, C++ (20)
Kernel (8)
Guitar (19)
잡담 (77)
etc (8)
who am i (8)
보안 이야기 (88)
Tools (3)
월간 마이크로소프트웨어/그.. (28)

글 보관함