버퍼 오버플로우 검사

 | C, C++
2009.11.08 22:15

버퍼 오버플로우 검사




에효... 얼마전에 초난감 삽질로 반나절을 날렸습니다.
계속 변수들이 값이 바뀌고 애매한 위치에서 익셉션이 나고 난리길래
오만 삽질 디버깅 끝에 아래 코드가 문제라는 것을 알았습니다...;



4개짜리 배열 변수에다가 루프를 8번 돌아서 값을 입력하려고 했으니 -_-;
에혀... 봐도 너무 한심하네요...

저희쪽 코드가 워낙 하드코딩을 일삼는 짓이 많다보니... 뭐 copy & paste 의 폐해이자 동시에,
일차적인 원인도 저런 코드를 만든 저 자신에게 있지만 그래도 이런건 컴파일러에서 좀 잡아줫으면
좋겠구만... 하는 생각이 막 앞서네요 (반나절을 날린 댓가를 누군가에게 보상받고 싶은 마음일지도)

제가 아직 6.0 컴파일러를 사용해서 노망난 컴파일러에게 저런 것 까지 기대하는 것은
무리인 것일까 하는 마음에 2003 으로 한번 테스트를 해봤습니다.
VS 2003 이상에서는 아시다 시피 저런 옵션이 있죠.






그리고 빌드를 해봤습니다......결과는 !!!!!



















뭐.... 마찬가지네요...
저한테 VS 2008 은 없어서, 옆에 앉은 넘에게 한번 시켜봤는데
VS 2008 역시 역시 결과는 마찬가지 였습니다.

컴파일러가 체크해 주는 BOF 의 기준은 어디까지일까 하는 생각을 갖게 하네요.
파고들어 보고 싶지만 아으 이걸로 (이렇게 멍청하게도)시간을 날려보니까 웬지 더이상
건드리기 싫다는 생각도 듭니다 :p

혹시 알고 계신 분은 공유해 주세요 ~



window31.




Posted by window31


댓글을 달아주세요

  1. 2009.11.08 23:28 신고
    댓글 주소 수정/삭제 댓글
    Visual Studio 2005의 Code Analysis 기능
    http://eslife.tistory.com/entry/Visual-Studio-2005%EC%9D%98-Code-Analysis-%EA%B8%B0%EB%8A%A5
    를 써 보면 어떨까요?
    저희는 CI 툴에 연동해서 쓰고 있는데, 도움 많이 받고 있습니다. :)
    • 2009.11.13 20:19 신고
      댓글 주소 수정/삭제
      아 2005는 이런 좋은게 있었군요...
      2003에는 없네요 ㅠ ㅠ 좋은정보 감사합니다 !
  2. 2009.11.09 04:33 신고
    댓글 주소 수정/삭제 댓글
    먼저 저 컴파일러 옵션에 있는 /GS는 static analysis, 즉 컴파일할 때 버퍼 오버런을 알려주는 기능이 아닙니다. /GS는 런타임시에 스택 오버플로우가 감지되면(힙 오버플로우는 아니고요) assertion을 띄어주는 것입니다. 아마 이 옵션을 켜고 실제로 실행하면 assertion이 걸릴 것 같은데요. 감지하는 방식은 아마 canary value를 써서 하는 것일 겁니다.

    원하시는 것은 위에 박피디 말씀처럼 static analysis로도 알 수 있습니다.
    http://msdn.microsoft.com/en-us/library/ms182025.aspx

    올려 놓으신 경우는 정적 분석으로는 아주 간단하게 잡을 수 있는 경우입니다. 포인터도 없고 루프 바운드도 상수이고 하니 아주 간단하죠. 학부생들에게 숙제로 내도 될 정도로 쉽습니다 ㅎㅎ

    (웬만하시면 그냥 영문 VC++을 쓰실 것을 강력히 권장합니다. 그래야 해당 컴파일러 옵션이나 에러 코드를 보고 쉽게 구글링할 수 있습니다. 버퍼 보안 검사... 구조체 멤버 맞춤... 작은 형식 검사??)
    • 2009.11.13 20:16 신고
      댓글 주소 수정/삭제
      보안모듈은 더러운 상황이 많아서 상위 컴파일러로 함부로 포팅할 수 없는 난관이 많습니다.
      그래서 아직 울며 겨자먹기로 6.0 을 사용하고 있고요, 2003은 sln로 된 프로젝트 줏어와서
      빌드하는 용으로만 사용하기 때문에 별로 영문 컴파일러에 대한 필요성을 못느낍니다. 그냥
      가끔 그러시는 분들은 계십니다 "쪼팔리게 한글판 쓰냐?" 별로 개의치 않습니다 ㅎㅎ
      물론 6.0 은 영문판 아니면 메뉴 선택조차 제대로 못 하겠지만요 ㅎㅎ (근데 6.0도 한글판이 있나요?)
  3. 2009.11.09 09:43 신고
    댓글 주소 수정/삭제 댓글
    저 기능은... 지정한 버퍼 뒤에 추가로 버퍼를 할당해놓고 특정 값을 memset해놓았다가, 실행후 그 "특정 값"이 변경되었는지 검사하여 버퍼오버플로우를 체크하는 기능이라고 알고 있습니다. 말하자면... 런타임에 체크해주는 기능이란 얘기죠. 김민장님께서 잘 설명해주셨네요. ^^
    • 2009.11.13 20:17 신고
      댓글 주소 수정/삭제
      아하 그렇군요~
      이름 때문에 헷갈렸어요-_-; 설명 감사합니다~! 하나 배웟네요 : )
  4. 2009.11.16 16:54 신고
    댓글 주소 수정/삭제 댓글
    http://blogs.msdn.com/vcblog/archive/2009/03/19/gs.aspx

    혹시나 도움이 되실지...

    From Zeratul
  5. kernel0
    2009.11.23 03:15 신고
    댓글 주소 수정/삭제 댓글
    ParkPD님이 써놓은 CodeAnalysis 뿐만이 아니라 외부툴인 pc-lint 라는 정적 체크툴이 있는데요. 그걸 쓰시면 플랫폼 교환없이 찾아내실 수 있겠네요. 가격은...30만원정도?

vtcp SDK

 | C, C++
2009.07.01 01:38

vtcp SDK



UDP 의 장점과 단점, 뭐 모르시는 분 없으시죠.

UDP 장점을 이용하고 단점은 극복한 VTCP 라는 라이브러리가 있습니다.
신뢰성 있는 UDP 라이브러리 라고나 할까요.
짱꼴라들이 만든건데요, 최근에 접한 악성코드가 이 라이브러리를 이용해서 제작해 놓았길래
한번 살펴보게 되었습니다.

구글링해보니 어떤 짱개 사이트에 이렇게 훌륭하게 SDK 가 있네요.
소켓 API 가 모두 구현되어 있고 비동기 IO 까지 지원해준다는 것 같은데
한번 궁금하신 분들은 써보시고 말씀 좀 해주세요 :)
(어차피 UDP 많이 쓰시는 네떡 or 겜 개발자들은 이미 더 훌륭하고 좋은거
만들어서 가지고 계시겠지만 : ) )


VC++UDP实现可靠传输(文件)(虚拟TCP3.0)
신뢰성 있는 전송으로 VC++UDP를 구현하다 (SDK) (가제:TCP 3.0)

http://www.cnasm.com/view.asp?classid=50&newsid=316




저 사이트에서는 뭐 어이없는 자료도 있고(누구나 다 아는) 
재밌는 자료도 뭐 그러네요 ㅎㅎ

Posted by window31


댓글을 달아주세요

  1. 2009.07.01 09:17 신고
    댓글 주소 수정/삭제 댓글
    아마도 많은 분들이 자체적으로 구현해서 사용하고 계실것 같은데, 알려주신 자료도 참고해보면 좋을듯 싶은데요~ ^^ 감사~
    • 2009.07.04 00:07 신고
      댓글 주소 수정/삭제
      네 거의 글쵸.. 자세히 보니 머 별건 없는듯 ㅋ

섹시한 모니터링

 | C, C++
2009.04.29 21:14

섹시한 모니터링





아주 웃긴 CPU 모니터링 체크 프로그램이 있네요.

http://hotbabe.planlos.org/download.html

설명이 필요없습니다. 직접 써보셔야 압니다.

가장 빨리 테스트 할 수 있는 방법은 프로그램을 실행해 놓고 백신 같은거 돌려서
CPU 를 최대한 올라가게 만드는 겁니다.
그러면 저 아해가 CPU 점유율에 따라 옷과 관련된 어떤 액션을 취할겁니다 ;;;

남자분만 쓰시는게 좋을듯 ;




사용자 삽입 이미지



SetTimer()로 만들어 두어서 그런지, CPU가 찰 때 즉시즉시 반영이 되지 않던데,
스레드로 만들고 우선순위 팍팍 높여놓았다면 더 좋지 않았을까 하는 생각이 드네요 흐흐흐

프로그램의 요점은 비트맵 4개 넣고 투명 속성을 CPU 율에 따라 달리 해 준다는 것
CCpuUsage 클래스는 그대로 가져다가 쓸만하네요.
소스까지 오픈되어 있으므로 한번 보세요 :)

성희롱 소지가 있으므로 여직원분들이 계신 앞에서는 실행하지 마시고...
(그러나 참고로 이걸 저한테 보내주신 분은 여자분이라는 것 ; )



저는 절대적으로 CPU 체크 소스를 공유할 목적으로 이 포스팅을 한겁니다 !!!

Posted by window31


댓글을 달아주세요

  1. 2009.04.29 21:46 신고
    댓글 주소 수정/삭제 댓글
    감사합니다 ㅎㅎ
  2. 2009.04.30 09:16 신고
    댓글 주소 수정/삭제 댓글
    오~ cpu사용률을 체크하는 공부를 하기에 너무나도 좋은 소스이군요. 정말 공부만을 위한 이런 공유 감사합니다.
    공부할려고 소스대신 리소스(res/*.bmp)를 집중적으로 봤습니다.
    • 2009.05.01 16:35 신고
      댓글 주소 수정/삭제
      최근 댓글중 가장 욱긴 거 같아요 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
    • 2009.05.02 03:23 신고
      댓글 주소 수정/삭제
      오~~ jz님 Hotbabe~~(퍽) ㅋㅋㅋ 저도 공부를 위해서 CHotBabeWnd::DrawHot() 함수를 고쳐보았습니다... cBitmapX 를 고쳐보았죠~~~
  3. 조차장
    2009.04.30 10:12 신고
    댓글 주소 수정/삭제 댓글
    포스팅으로 올라오다니,, 집요하시군요 ㅋ
    • 2009.05.01 16:35 신고
      댓글 주소 수정/삭제
      언제 차장으로 진급하셨습니까 ;
  4. 상차장
    2009.04.30 10:17 신고
    댓글 주소 수정/삭제 댓글
    ㅇ ㅣ긋바요
  5. 2009.04.30 12:15 신고
    댓글 주소 수정/삭제 댓글
    오오오~~ +_+ 바로 다운 클릭 (헤벌레)
    =0= 좀 살펴보고 제 블로그에다가도..ㅋㅋㅋ;;
    좋은거 감사용~~ +_+
    • 2009.04.30 12:24 신고
      댓글 주소 수정/삭제
      -0- 아무래도 주위 눈치보여서;;
      게임 창모드로 만들어놓고..
      살짝 걸쳐두고 테스트해봤는데;; =0=;; 이건 뭐..ㅋ
      98% ~ 100% 일때의 그 적나라함이란..쿨럭;;.
    • 2009.05.01 16:36 신고
      댓글 주소 수정/삭제
      음 일부러 CPU 사용율을 계속 높히고 싶어 :$
  6. 2009.04.30 16:40 신고
    댓글 주소 수정/삭제 댓글
    일하다가 설치해서 볼려고 했는데...
    하마터면 큰일날 뻔했네요...ㅋㅋㅋ
    • 2009.05.01 16:36 신고
      댓글 주소 수정/삭제
      음 저희 층에는 직원의 남성 비율이 100%라서 딱히 가릴건 없네요 ㅋ ;;
  7. 2009.05.01 15:03 신고
    댓글 주소 수정/삭제 댓글
    저도 절대로 CPU 점유율 확인해보기 위해서 다운받았습니다.
  8. p01nt
    2009.05.10 07:07 신고
    댓글 주소 수정/삭제 댓글
    지금 열심히 무한루프 돌리고 있습니다...흐흐
  9. 2009.05.18 10:51 신고
    댓글 주소 수정/삭제 댓글
    *-_-*

    PROCESS_INFORMATION pi;
    STARTUPINFOA si;

    SetProcessAffinityMask(GetCurrentProcess(), 2);
    memset(&pi, 0, sizeof(PROCESS_INFORMATION));
    memset(&si, 0, sizeof(STARTUPINFO));

    si.cb = sizeof(STARTUPINFOA);
    si.dwFlags = 0;

    CreateProcessA(".\\HotBabe.exe", NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);

    SetProcessAffinityMask(pi.hProcess, 2);
    printf("wow, naked function?!\n";);
    ResumeThread(pi.hThread);
    while(1)
    {
    //char *p = (char *)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, 1024);
    DWORD dwret;

    HANDLE hFile = CreateFile(L"\\.\C:\\dummyda.dat", FILE_ALL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_ALWAYS,
    FILE_ATTRIBUTE_NORMAL,
    0);

    //WriteFile(hFile, p,1024,&dwret, 0);
    }

블로그에서 돌아가는 음악 파일 가져오기




음악이 흘러나오는 블로그가 많습니다. 그런데 아쉽게도 "다른 이름으로 저장" 같은 기능이
없는 관계로 그 음악을 듣고 싶으면 꼭 그 블로그에 방문해야만 합니다. mp3 player 등에
넣은 후 들으면서 다니고 싶어도 그럴수가 없습니다. 좋은 방법이 없을까요?

블로그에 접속한 뒤 울려퍼지는 노래는 사실은 내 컴퓨터 어딘가에 저장되어 있습니다.
파일로 저장되어 있겠죠, 그리고 블로그는 인터넷 익스플로러 프로세스입니다. 자 여기까지
보았으면 무언가 감이 빡 오지 않나요? 파일이라면 handle 이 있을겁니다 !
즉, iexplore.exe 의 handle list 를 구하고, 음악 파일 확장자를 찾아본다면
음악 파일이 어디있는지 알 수 있겠죠, 그것을 나의 폴더로 복사하기만 하면 됩니다.

한번 구현해 볼까요 :)

먼저 iexplorer.exe 의 pid 를 구합니다. 인터넷 익스플로러를 여러 개 띄워놓을 수도 있으니
벡터를 썼습니다.


핸들 리스트를 구하기 위해서는 ntdll 의 api 가 필요한데요, 우리가 써야 할 것은
ZwQuerySystemInformation, ZwQueryObject, ZwClose 입니다.

그리고 몇가지 undocument 구조체가 필요합니다 (아, 더이상 undocument 가 아니죠 ㅎㅎ)
얘네들을 선언해놓을 필요가 있습니다 (인터넷을 잘 찾으면 널려 있습니다)

SYSTEM_HANDLE_INFORMATION,
OBJECT_BASIC_INFORMATION,
OBJECT_TYPE_INFORMATION,
OBJECT_NAME_INFORMATION 등입니다.


이제 갑니다. ZwQuerySystemInformation() 을 사용합니다. 첫번째 인자로 
SystemHandleInformation 을 준다는게 요점입니다.



그런데 사실 한 프로세스에 handle 은 엄청나게 많겠죠. 그중에서 우리가 필요한건
file handle 입니다. 따라서 그것만 추려내면 됩니다. 그 속성은 OB_TYPE_DEVICE 로,
OS 마다 값이 다르므로 판별할 필요가 있습니다. 아래는 셋팅 코드입니다. XP에서만
돌아가게 만들거면 강제로 0x1C 로 집어 넣으세요 ㅎ




자 이제 한번 핸들 갯수만큼 루프문을 돌아 볼까요~
고고씽!


Object Type 은 File , Mutant, Event 머 이런걸 가리키는 겁니다.
우리는 당연히 File 만 가져옵니다.
그리고 ZwQueryObject() 를 돌면서 ObjectNameInformation 를 가져옵니다. 이제 수많은
파일 핸들 리스트가 쭈욱 뽑힐겁니다.

근데 경로가.... \Device\HarddiskVolume1\Documents and Settings\.... 이딴식으로
나옵니다. C:\Document and Setting\ 이런식으로 나오면 아주 편할텐데 말이죠...
윈도우즈가 깔린 드라이브를 구해주는 API 아시는 분 혹시 있나요...;
전 무식해서 이렇게 구했습니다.

1. GetWindowsDirectory() 로 C:\WINDOWS 같은걸 구한다.
2. \ 이후의 WINDOWS를 짤라버린다.
3. C:\ 만 남는다.



그것 조차 귀찮으신 분은 이 플그램을 쓰는 모든 유저는 C:\ 에 윈도우즈를 깔아야만 한다 라고
가정하신후 C:\ 로 하드코딩하세요 ㅋㅋ 뭐 돈받고 팔아먹을 플그램도 아닌데요 :)
(아 이런 마인드 진짜 좋지 않습니다 ㅠ ㅠ)

자, 파일의 풀패스가 pOni->Name.Buffer 에 유니코드로 들어옵니다.
음악 파일인지 비교하시고 맞다면 로그 한방 찍어주고~



자 이제 복사하면 끝이죠.

 


실제로 만들어보니 아주 잘 돌아갑니다.
우우우우우우웁스 0.001 입니다.


사용자 삽입 이미지


실제로 이런식의 구현은 어디 남의 서버에 침투해서 파일을 빼오는게 아니고
그냥 자기 PC 의 어딘가에 숨어있는 파일을 내가 아는 폴더로 복사하는 것 뿐입니다.
따라서 해킹툴 제작과는 전혀 상관없음을 말씀드립니다..

학습/연구 목적이므로 툴과 풀 소스는 따로 베포하지 않습니다.
단지 file handle 을 이런식으로 가지고 놀 수 있다는 것을 보여주기 위해 포스팅했습니다.
쉬운 예를 들기 위하여 블로그에서 음악 파일을 가져오는 것에 비유해 보았고요

file handle, 파고들어보면 재미있는 내용이 많습니다 :)





window31. 2009년 4월





ps
당연히 플래시 파일인 swf 도 가져올 수 있겠죠 :)

Posted by window31


댓글을 달아주세요

  1. ks
    2009.04.18 23:00 신고
    댓글 주소 수정/삭제 댓글
    더 쉽게 할 수도 있는... 파폭에 DownThemAll이라는 플러그인이 있어서 다운로드 할 수는 있네요...
    그런데 이건 ActiveX가 재생하는 것까지 가능한가요?
    • 2009.04.19 16:27 신고
      댓글 주소 수정/삭제
      아마도 스트리밍 방식의 ActiveX가 아니면 거의 다 받아질 것으로 보입니다. (표준 Wininet API 역시 기본값으로 캐시를 사용하고 있으니...)
    • 2009.04.19 22:05 신고
      댓글 주소 수정/삭제
      핸들만 구할수있으면 다됩니다 : )
  2. 2009.04.19 16:24 신고
    댓글 주소 수정/삭제 댓글
    프로그램 내용과는 상관 없지만... 나루토를 즐겨 보시는 것 같군요...^^;; (저도 개인적으로 재미있고 보고 있는 애니메이션입니다.) :)
    • 2009.04.19 16:30 신고
      댓글 주소 수정/삭제
      그나저나... \\Device\\HarddiskVolume1\\... 를 DOS Logical Drive 로 바꿔주는 API가 있는 것으로 알고 있는데...(아니면, 파일 매핑 객체 생성해서 파일 매핑 후 psapi.dll의 GetMappedFileName API를 쓰면 조금 더 이쁜 모양(?)이 나오죠...^^) 만일 상용화 or 배포하는 경우에는 그걸 쓰는 것이 훨씬 정확할 것 같네요...^^;;
    • 2009.04.19 16:32 신고
      댓글 주소 수정/삭제
      그리고 Object Type Number 는 OS 에 따라 다른데, switch-case 로 버전 별로 넣어주어도 동작하지만, 전방 호환성을 유지하고 싶은 몇몇 프로그래머분들은 CreateFile() 등으로 NUL 파일의 핸들을 연 다음, 해당 핸들의 Object Type Number 를 추출하더라고요...^^;;
    • 2009.04.19 22:06 신고
      댓글 주소 수정/삭제
      ㅎㅎ 나루토를 별로 즐겨보진 않지만 하다보니 나루토 이미지가 멋진게 많아서
      어케 자주 사용하게 되네요 : )
      위 좋은 정보는 감사 드려요 ! ^^
  3. 2009.04.19 20:11 신고
    댓글 주소 수정/삭제 댓글
    옷~ 멋지군요. ;)
    핸들을 이렇게 사용할 수도 있네요. ㅎㅎ 좋은 글 잘 보고 갑니다. ^^
    (인터넷 임시 파일 디렉토리를 뒤져도 비슷한 일을 할 수 있을 것 같다는 예감이 드는군요. ㅎㅎ)
    • 2009.04.19 21:34 신고
      댓글 주소 수정/삭제
      Find***UrlCacheEntry 라는 API가 있으니 어렵지 않게 구현할 수는 있겠죠...^^;;
    • 2009.04.19 22:07 신고
      댓글 주소 수정/삭제
      아하 인터넷 템프 폴더를 뒤져도 되겠군요
      그게 훨씬 쉽겠네요 ㅋㅋㅋ
  4. justlive
    2009.04.20 16:00 신고
    댓글 주소 수정/삭제 댓글
    카카시 선생 ㅜㅜ

    아이디어가 번쩍입니다. +_+

    좋은글 감사합니다.
    • 2009.04.20 19:00 신고
      댓글 주소 수정/삭제
      하하 아이디어는 무슨 ;;
      그냥 꽁수에 불과한 거랍니다 : )
  5. ks
    2009.05.01 20:11 신고
    댓글 주소 수정/삭제 댓글
    하다보니
    ZwQueryObject(hObj, ObjectNameInformation, ObjName, nObjectName, n)
    이 부분에서 몇 번 제대로 돌다가 그 이후로 이 함수 안에서 빠져나오질 않습니다... 왜 그러지...
  6. ks
    2009.05.02 01:14 신고
    댓글 주소 수정/삭제 댓글
    0FA9168C 6A 64 push 64h
    0FA9168E FF 15 AC 14 A9 0F call dword ptr ds:[0FA914ACh]
    0FA91694 80 0D 76 D0 C0 0F 04 or byte ptr ds:[0FC0D076h],4
    0FA9169B EB EF jmp 0FA9168C

    이부분에서 무한루프 ㄱ-;;;
  7. 2009.05.10 20:43
    댓글 주소 수정/삭제 댓글
    비밀댓글입니다
  8. 2009.05.15 11:03
    댓글 주소 수정/삭제 댓글
    비밀댓글입니다
  9. justlive
    2009.05.16 01:07 신고
    댓글 주소 수정/삭제 댓글
    PSYSTEM_HANDLE_INFORMATION aHandles = (PSYSTEM_HANDLE_INFORMATION)(pULONG + 1);
    ->
    PSYSTEM_HANDLE_TABLE_ENTRY_INFO aHandles = (PSYSTEM_HANDLE_TABLE_ENTRY_INFO)(pULONG + 1);

    이건것 같아욤..
  10. 2009.06.15 11:30 신고
    댓글 주소 수정/삭제 댓글
    좋은 글 잘 보았습니다.
    시스템 볼륨 얻을때 ShGetFolderPath 를 이용하시면 좋을 것 같네요.
    http://msdn.microsoft.com/ko-kr/library/bb762181(en-us,VS.85).aspx
  11. 나디아
    2010.11.25 02:19 신고
    댓글 주소 수정/삭제 댓글
    전에 쓰던거... 디바이스명을 도스형태로.. ^^


    //////////////////////////////////////////////////////////////////////////
    BOOL DevicePathToDosPath(LPCTSTR lpszDevicePath, LPSTR lpszDosPath, DWORD dwMaxSize)
    {
    if(!lpszDevicePath || !lpszDevicePath) return FALSE;

    // \Device\HarddiskVolume2\Program Files (x86)\Internet Explorer\iexplore.exe

    CXString szDrv;
    CXString szDevicePath=lpszDevicePath;
    CXString szDevPath;
    szDevicePath.MakeTrimLower();
    szDevPath.SetBuffer(_MAX_PATH+1);

    DWORD dwLD=GetLogicalDrives();
    for(DWORD i='A'; i<='Z'; ++i)
    {
    if((dwLD&0x1)==0x1)
    {
    szDrv.Format("%C:", i);
    szDevPath="";
    if(QueryDosDevice(szDrv, (LPSTR)szDevPath.GetString(), MAX_PATH))
    {
    szDevPath.MakeTrimLower();
    if(szDevPath.Compare(szDevicePath, szDevPath.GetLength())==0)
    {
    sprintf_s(lpszDosPath, dwMaxSize, "%s%s", szDrv, szDevicePath.GetString()+szDevPath.GetLength());
    return TRUE;
    }
    }
    }
    dwLD=dwLD>>1;
    }

    return FALSE;
    }

    //////////////////////////////////////////////////////////////////////////

깔끔한 코딩

 | C, C++
2009.02.24 23:54

깔끔한 코딩




아으 거의 한달만에 글을 쓰는거 같네요...
2월에는 개인적인 일도 많았고 그밖의 사건사고도 끊이지 않았는지라 ;

오늘은 코딩이라는 주제에 대해 한번 뭔가 써볼까 합니다.
요즘은 그런 생각이 자주 듭니다.
깔끔한 코딩이란 무엇일까 하는...

흔히 이런얘길 하죠...
"내 코드 더러워서 못줘."    <- 자학
"니 코드는 왜이렇게 개같냐..."    <- 비난
"A가 짠거 봤냐? ㅂㅅ같애!"     <- 뒷따마


음~ 사실 깔끔한 코딩과 더러운 코딩이라는 경계선이 존재한다고 분명하게 믿고 있었는데
요즘은 그 라인이 모호해진다는 느낌이랄까
깔끔하다는 얘기가 상대적인 것이지 않은가 하는 생각이 많이 듭니다.

아주 단순한 예를 들어보겠습니다.


<코드 A>


<코드 B>

<코드 A> 스타일을 즐겨 사용하시는 분이 있고, <코드 B> 스타일로 가시는 분들이 있습니다.
누가 더 깔끔하다고 말할 수 있는 것일까요?

하나만 더 들어보겠습니다.


<코드 C>


<코드 D>

중간중간 리턴코드로 걸러주시는 분이 있고, return 모시기 삽입 없이 항상 참인 상태가
지속되도록 코딩을 하시는 분이 계십니다.
<코드 C>와 <코드 D>의 경우 역시 누가 더 깔끔하다고 말할 수 있을까요?

깔끔하다는 의미라는 것이 상대적이라는 냄새가 서서히 납니다.
제 생각이긴 하지만, 보통 개발자들은 결국 자기 눈에 맞지 않으면, 혹은
자기 스타일이 아니면 더러운 코드라고 느끼는 것 같습니다
.

물론 그렇다고 해서 정말 더러운 코드가 없는건 아닙니다.
예를 들어 이런건 누가봐도 정말 더러운 코딩이죠. 무한 if 문입니다.


<코드 E> 끝없는 if 문

머 조건과 필터링이 걷잡을 수 없이 늘어나는 경우가 분명 있긴 하지만 한 조건 안에
10개가 넘는 if 가 들어가면 사실 뚜껑이 열리는 것은 분명합니다 (어시스트 없으면 죽습니다
아 ㅅㅂ 어느게 어느 중괄호야 !!!! 대략 이런 반응....)
하나 더 있습니다.
알 수 없는 변수명이죠.


<코드 F>

for 루프 카운터 변수가 아닌, 일반 변수를 이딴식으로 지어 놓은 것을 보았을 때,
그리고 내가 그 변수명으로 인해 헷갈려서 큰 사고를 칠 뻔했을때, "이 코드의 주인공을
찾으면 반드시 목을 비틀고 만다!"
라는 생각 해보신 분 분명 있을겁니다.

다시 원래의 주제로 돌아와서,
깔끔한 코드의 기준이 상대적이라는 말을 뒷받침해줄 예가 하나 더 있습니다.
사수에게 코드를 인계받았을 때는 물론 이런 얘긴 하지 않지만
보통, 자기랑 실력이 비슷하거나 혹은 더 못한 전임자에게 코드를 인계받았을 때는
소스를 분석하다말고 거의 십중 팔구 이런 소리를 합니다.

"ㅇ ㅏ!!! 것참 더럽게 짜놨네 ㅅㅂ 내가 처음부터 다시 짜고 싶다 !"

그래서 일부의 경우는, 부분부분 리펙토링을 하거나 아니면 정말 자기가 다시 처음부터
코드를 만들기도 합니다. 그러나 시간이 지나고 자기도 유지보수의 압뷁에 시달리다 보면
결국 어느 순간은 "일단 구현하고보자" 의 코드가 여기저기 생겨나게 되고 같은 현상이
되풀이 됩니다. 그리고 그사람이 떠날 때 그 후임자가 코드를 받는다면, 역시 똑같은
소릴 하겠죠 :)

저는 업무 특성상 "실시간 순발력"과 "일단 만드는게 먼저"를 요하는 일만 계속 해왔기 때문에
설계 능력도 떨어지고, 구조적인 감도 하나도 없습니다.
빨리! 빨리! 그저 고속 코딩만을 해왔죠...
뭐 빨리 해야 윗분들이나 고객들이 좋아하고, 저도 그냥 설계다 뭐다 핑계로 질질끄는게 싫어서 ;

그래서 정말 저의 코드는 더럽습니다.
그냥 머 ... 더럽지만 퍼포먼스 테스트만은 잊지 않는 정도의 수준이랄까 ;
주로 남한테 기생하는 기능만 만들었던 지라 ;; 내형적으로는 더럽더라도 외형적으로는 깔끔하게
잘돌아가야 하니까요. lol

어쨌든 그래서 사실 많은 개발자들이 자신의 목숨에 비할만큼 가치를 높게두는 코딩 자존심이나 
방법론 등에 대한 이해도 별로 없고 또 잘 알지도 못합니다.  그래서 코딩이라는 일을 또다른
학문으로 승격시키며 출간되는 수많은 책들... 본것도 없고 잘 모릅니다 ㅎ ; 뭐 근데 그건 저
뿐만이 아니고 라이브 서비스를 주로 하셨던 분들은 대부분 그렇지 않나 싶기도 합니다.

어쨌든 그래서 저는 요즘들어 이런 철칙들이 더욱 중요하다고 느껴집니다.
"남의 코드 씹지 말자."
"내 코드 씹히더라도 개의치 말자."
 

인간들이 꺼려하는 기본 규율에만 어긋나지 않는다면, 코드가 더럽다는 것은 다
상대적인 것이 아닐까. 하는 생각이 많이 듭니다. 어차피 실전에서 변수명을 저따위로 두거나
하나의 함수 길이를 1000줄이 넘도록 작성하거나 하는 일은 많지 않으니까요.

더럽고 깔끔하다는 상대적인 개념만 극복하면, 코딩에 대해 씹힌후 기분 나쁠 일도,
타인을 씹을 일도 없는 게 아닐까 하는게 그냥 요즘 드는 생각입니다.


window31. 2009년 2월.
Posted by window31


댓글을 달아주세요

  1. 사당최
    2009.02.25 10:08 신고
    댓글 주소 수정/삭제 댓글
    학창시절 인공지능 오목을 만들면서 함수 하나가 10미터가 넘었던 기억이 (-_-;) 쿨럭
    • 2009.03.04 22:27 신고
      댓글 주소 수정/삭제
      10미터 너무 심한거 아냐 -_-;;
      그나저나 우리 이제 술좀 먹자 ;
  2. 2009.02.25 10:11 신고
    댓글 주소 수정/삭제 댓글
    저도 개발하면서 느끼는게 본인이 보았던 소스가 프로그래밍 될 당시 상황을 잘 알지도 못하고 코드 씹는건 언젠가 본인에게 돌아온다는 것. 그리고 자신이 혼자 볼게 아니라면 변수나 함수명처럼 최소한의 예의는 지켜야 한다는 것이죠.
    연초는 무슨 일 때문인지 매년 정신 없는거 같네요. 올 해도 순식간에 지나갔군요.
    • 2009.03.04 22:28 신고
      댓글 주소 수정/삭제
      그렇죠 ^^; 그런데 당시 상황을 알수가 없다는 것이 문제 ;;
      그런데 국립국어원이라는 사이트를 덕분에 알게 됐네요.
      이 단체는 줄임말로 뭐라고 불러야 할까요.. 국가정보원은
      국정원 이라고 부르는데...그렇다면 여기는 국국원? ;; :p
  3. 2009.02.25 11:25 신고
    댓글 주소 수정/삭제 댓글
    완전 공감되는 글~ -0-b..
    ( 추천같은거 있음.. 바로 눌렀을 듯;; )
    모 모듈 새로 만들때~~
    switch 문 쓰기도 난감한 상황에서..
    서버쪽 모듈이라 예외처리 남발하기 뭣해서..
    if - else 로.. 삽질했던 기억이 나네요~ㅋㅋㅋㅋ
    • 2009.03.04 22:30 신고
      댓글 주소 수정/삭제
      추천버튼을 못찾았으면 밥을 사고
      나도 막상 짤때는 if - else 가 더 편하다-_-
      그런데 나중에 코드 볼땐 "ㅅㅂ switch 를 써야지 if질을 해놨네..." 이렇게 되지 : )
  4. 2009.02.25 18:50 신고
    댓글 주소 수정/삭제 댓글
    8중 for문 썼던 기억이 ㅎㅎ
    • 2009.03.04 22:30 신고
      댓글 주소 수정/삭제
      8중 for ;;; 어떤 알고리즘이시길래 : )
  5. 신고
    2009.02.28 02:23 신고
    댓글 주소 수정/삭제 댓글
    http://websecurity.tistory.com/
    이 블로그좀 가보세요. window31님 블로그 내용 그대로 다 뱃겨놨내요
    저작자 표시도 없구
    • 2009.03.04 22:31 신고
      댓글 주소 수정/삭제
      네. 그렇군요. 음 머 알아서 지우겟죠
  6. 2009.03.02 13:49 신고
    댓글 주소 수정/삭제 댓글
    오늘 처음 여기 방문했는데, 공감가는 글이 있어 댓글 달아봅니다.
    사실 모든 코드는 사람에 따라서 자의적으로 해석되는 경우가 많죠.
    그래도 대다수가 공감한다면 그것이 정답에 가까울 확율이 높다 라고 생각할수 있을것 같습니다.
    위의 문제는 "code craft"라는 책의 6장에서 언급이 되어 있습니다.
    그렇다고 C언어 자체로는 좋은 해결점이 있는건 아니고, 경우에 따라 다른것 같습니다. C++에서는 그나마 해결점을 찾아서 보여주고 있습니다.
    혹시 관심있으시면 찾아보시길 바라오며, 그런데 이 책이 그렇게 좋지는 않네요.^^ 안그러면 추천 날렸을텐데.. 하여튼 모두가 생각하는 그런 문제인듯합니다.
    • 2009.03.04 22:35 신고
      댓글 주소 수정/삭제
      CodeCraft 좀 보다가 제 취향이 아니라서 접었습니다.
      뭐 사실 제가 이 글에 언급한 내용에서 나온 거 중 하나가
      "알고 있지만 고치지 못하는 거" 입니다.

      코드 크래프트나 코드 컴플릿이나 뭐 마찬가지 맥락의 책이라고 생각합니다.

      내용 자체는 좋죠 ^^; 단지 실무에서 그걸 지키기 어려운 상황이
      항상 존재한다는 것
      제 생각에는 대학생이나 개발1년차들이 봐야할 책이라고 생각됩니다.
      뭐 그렇다고 해서 제가 그사람들보다 낫다는 얘긴 절대 아니고요 ;;
      더럽혀진 몸에 보기보다는 대가리가 깨끗할 때 보아라.. 라는 뉘앙스? ㅎㅎ
  7. 2009.03.02 17:35 신고
    댓글 주소 수정/삭제 댓글
    *^^* 좋은 글 잘 읽고 갑니다~~

    더불어 마소 잡지 3월호의 글도 재미있게 읽었어요 ^^

    p.s: 그런데 간혹 이런 것도 논의가 되기도 하더라구요..

    if(a == 0)
    {
    // ...
    }

    if(0 == a)
    {
    // ...
    }

    깔끔한건 둘째치고 생성된 바이너리를 기준으로 볼 때 둘다 똑같은 코드인데 말이죠...
    • 2009.03.03 09:55 신고
      댓글 주소 수정/삭제
      이런건 코딩상의 실수를 줄일때 많이 도움이 된다고 하더군요;;.
      (변수 == 상수) 나.. (상수 == 변수나) 바이너리상..
      차이는 없겠지만..
      코딩할때 '==' 해야될 것을 실수로 '=' 로 하게 된다면;
      (변수 = 상수)는 문법은 맞기땜에 에러가 안뜨지만,
      (상수 = 변수)는 틀린 문법이기에..
      사전에 이런 실수를 방지할 수 있는걸로 말이죠..;ㅋ
    • 2009.03.03 20:17 신고
      댓글 주소 수정/삭제
      *^^* 물론 그렇기 때문에 저렇게 쓰는거겠죠? :p

      그런데 가끔 속도가 더 빠르다고 해서 밑에껄 선호하는 사람이 더러 있어서...;;;
    • 2009.03.04 22:35 신고
      댓글 주소 수정/삭제
      음 두사람의 훌륭한 토론에 제가 낄틈이 없군요 ㅎ
  8. moonistar
    2009.03.02 22:39 신고
    댓글 주소 수정/삭제 댓글
    저도 개발 이제 1년 했는데,,, ㅡ.ㅡ;
    인수인계 받은 코드보고 정말 개떡같다.. 차라리 다 엎고 내가 짜고 싶다..
    라고 입에 달고 달았는데,,,
    뜨끔하네요,,, 다시 생각하게 되네요 ㅋ 내가 짜도 지금 같지 않을지,, ㅎㅎ
    첨으로 글 남기네요,,
    • 2009.03.04 22:37 신고
      댓글 주소 수정/삭제
      뭐 한번이라도 안 그래본 개발자가 어디있겠어요 ㅋㅋㅋ
      전 1년전에 제가 짠걸 보면서도 욕합니다.
      "아 정말 ㅄ같이 짰다. 이당시에 코딩은 발로했나보네"
  9. 2009.12.03 03:24 신고
    댓글 주소 수정/삭제 댓글
    특히나 회사 코드는 좀 나은데, 오픈 소스 코드들은 유명한 프로젝트들도 잘 뜯어 보면 코드가 거의 개판 5분전이 많더라구요. 특히 GNU 어쩌고 하는 코드들이 좀 심하죠(아주 오래 전에 짜여진 소스들이 특히).

    그냥 아무리 개떡같은 코드도 읽고 수정할 수 있는 능력을 배양하는 것이 더 빠른 길이더군요. 복잡한 코드 리팩터링이나 다시 짜다가 알 수 없는 버그로 시간 허비할 수도 있고 말이죠.

    차라리 기존 리거시 코드에 테스트 루틴만 몇개 추가해 놓고 수정 들어 가도 작업이 빨라지더군요. 소스 한줄 고치고 테스트 돌리고 이런식으로 하는 거죠.
  10. Dual
    2010.10.29 16:55 신고
    댓글 주소 수정/삭제 댓글
    특히 FIX ME!!
    HACK!!
    NOT IMPLEMENTED
    같은 코멘트 들이 짜증나요,
    누가 고쳐주길 기대하는거지 ㅠㅠ

쓰레기 코드

 | C, C++
2008.11.29 15:41

쓰레기 코드




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

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



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

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

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



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




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

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

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

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

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

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


2008년 11월.
window31.

Posted by window31


댓글을 달아주세요

  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
    댓글 주소 수정/삭제 댓글
    비밀댓글입니다
  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());
    }
    }
    이라는...

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

네이트온의 디버그 메시지




아으 저번주까지는 정말 폭풍같은 한주였네요.
몸은 졸고 있는데 계속 손가락 끝으로 코딩은 지속되고 있고
눈은 감고 있는 거 같은데 무언가 리버싱 흔적의 화면캡쳐와 코드설명은 늘어만 가고
매일 택시타고 귀가하니 좋긴 했다만 암튼 비몽사몽 중에도 생기는 아웃풋이 신기하던 ;;
밤샘코딩이 사실 엿같긴 하지만 이번엔 그래도 개 하기싫은데 억지로 하는게 아닌
즐겁게 일할수 있었다는게 그나마 다행이었던 것 같습니다.

얼마전부터 네이트온에서 디버그뷰에 공란으로 되어 있는 디버그메시지를 엄청 찍어대고
있습니다. 저 같은 경우는 안티디버깅 엔진 개발만 주로 했는지라 사실 비주얼 스튜디오로
디버깅하는게 별로 익숙치가 않습니다. 걍 로그 찍는게 더 편하죠 -_- 디버그 모드로
불안불안 실행되는 플그램도 제 체질이 아니구요 (어셈블리 코드로 확인이 필요하다면
빌드한 다음에 아예 걍 olly 로 열어봅니다)

머 그래서 어쨋든 항상 사용하는 log Class 가 있고 OutputDebugString도 가변인자
버전으로 맹글어서 많이 의지하여 사용하고 있는데, 그런 상황에 다른넘들이 디버그뷰에
열라 찍어댄다면 참 짜증이 나죠. 최근엔 네이트온이 공란으로 찍어대는 디버그 메시지에
스트레스를 이빠이 받고 있습니다.
 
혹시 이거 프로세스별로 예외처리나 디버그 메시지 기록되지 않게 할 순 없을까 궁금해서
메뉴를 뒤져봤는데 Filter 라는 넘이 있드라구요, 거기다가 NateOnMain.exe를 넣어봤습니다.


사용자 삽입 이미지


아 근데 여전히 찍어대는 겁니다. 정말 ㅅㅂ 짜증나죠. 왜그럴까 생각하고 있는데
같이 일하는 넘이 한마디 하더군요.


사용자 삽입 이미지


그래서 pid 를 등록을 했습니다만, 이게 필터에 대한 설명을 자세히 보니, 이런!!!
Enter multiple filter match string separated by the ';', character......
이렇게 쓰여 있군요... pid 로 빼긴 빼지만 이게 프로세스 식별을 위한 pid 가 아니고
그냥 dbgview 에 pid 가 표시되면서 메시지 찍는데, 문자열에 그 내용이 찍히면
걍 무조건 빼는거였습니다 -_-

이렇게 필터링하면 아래와 같은 문제가 발생하죠, 대화를 보세요.

사용자 삽입 이미지


쵸큼 이해가 되지 않는 분들은 이 코드를 보면 바로 아하! 하실겁니다.
다음과 같은 코드가 있습니다.



결과를 보면 당연히 아래와 같겠죠.


사용자 삽입 이미지


근데 제가 네이트온이 디버그 메시지를 좇나 찍는게 짱나서 네톤의 pid 를 exclude 해버렸습니다.
네톤의 pid 는 공교롭게도 456 이었군요. 그리고 pid가 456인 네톤은 이제 더이상 디버그뷰에
메시지를 찍지는 않습니다. 만족하고 열심히 열혈 코딩을 하던중 어쩌다가 다시 위와 같은 코드를 
디버그뷰에 찍을 일이 생겼습니다. 그러나!!!!!!!!!!!!! 이번에는 이렇게 되어버리겠죠.


사용자 삽입 이미지


사용자 삽입 이미지

이런!!!! 중요한 디버그 메시지인 "ㅅㅂ 456" 이 없어져 버렸습니다. 이런 망할...

그래서 디버그뷰의 filter 기능은 별로 추천하지 않습니다.
그냥 아래와 같은 방법이 깔끔합니다.
NateOnMain.exe의 kernel32.dll OutputDebugStringW()를 retn 4 시켜버리는겁니다.

사용자 삽입 이미지

사용자 삽입 이미지

이제 깔끔해졌네요. 더이상 디버그 메시지가 난립하지 않습니다.

굳이 네톤에 국한된 얘기가 아닙니다. 디버그뷰 좀 띄워놓고 인터넷 여기저기 다니고
플그램 이것저것 쓰다보면 그 무수한 로그에 사실 넌덜머리가 납니다.
버그 찾는거 보다 많은 로그 속에서 내 로그 찾는 시간이 더 많다는 생각이 들기까지 하니까요.

상용소프트웨어 개발 하시는 분들 제발 디버그뷰에 메시지 찍는 버전으로 베포좀 하지 마세요.
릴리즈 빌드의 기본 매너라고 생각됩니다.

그리고 참고로 네톤을 리버싱한 내용으로 오인될 수가 있는데,
이 내용은 상용 소프트웨어를 리버스 엔지니어링/코드 패칭 한 것이 아니고
어디까지나 kernel32.dll 의 OutputDebugStringW()만을 건드린 것임을 다시한번 명시합니다.


window31. 2008년 10월.

Posted by window31


댓글을 달아주세요

  1. 2008.10.15 07:44 신고
    댓글 주소 수정/삭제 댓글
    아...저도 그런적이...있었는데...써먹어야 겠군요...
    잘보고갑니다...
    • 2008.10.18 17:56 신고
      댓글 주소 수정/삭제
      저만 그런게 아니라 다행이네요 ^^
  2. 2008.10.15 10:24 신고
    댓글 주소 수정/삭제 댓글
    필터를 "[456]" 으로 괄호까지 포함시키면 안나올것 같은데요^^
    네톤은 배포를 왜 저런걸 하나 모르겠네요
    디버그 코드 래핑하는걸 잊은듯
    저도 dbgview를 띄워봤는데, 저는 네톤 업데이트를 안해놔서 그런지 안찍힙니다;;;
    최근버전만 그런듯?
    ㅋㅋ
    잘보고 갑니다
    • 2008.10.18 17:58 신고
      댓글 주소 수정/삭제
      아하! 그런 방법이 있었군요.
      네 안찍히는 사람도 종종 있다고 하네요
  3. 하루
    2008.10.16 10:48 신고
    댓글 주소 수정/삭제 댓글
    무서운 사람..
    모든걸 캡쳐 /버럭/
  4. 2008.10.19 09:59 신고
    댓글 주소 수정/삭제 댓글
    호환(?)에 필요한 정보를 쉽게 얻을 수 없고 그 획득이 불가피(?) 한 경우 리버싱을 할 수 있다는군요.

    그럼 호환(디버그 메세지 삭제) 를 위해서는 리버싱 할 수 있는거 아닌가???
    • 2008.10.22 18:56 신고
      댓글 주소 수정/삭제
      뭐 그렇다면 다행이지만 이건 네이트온 리버싱이 아님
  5. chpie
    2008.11.01 11:53 신고
    댓글 주소 수정/삭제 댓글
    아하하 ㅎㅎㅎㅎㅎ
    "ㅅㅂ456" 이 증발한것이 넘 재미있네요 ㅋㅋ
    • 2008.11.07 02:15 신고
      댓글 주소 수정/삭제
      하하 유명하신 chpie 님 첫 댓글주신거 같은데
      반갑습니다 ^^;
  6. ggg
    2010.07.26 15:37 신고
    댓글 주소 수정/삭제 댓글
    정품 윈도우가 아니군요^^;
    • 2010.07.26 19:50 신고
      댓글 주소 수정/삭제
      정품인데요 일부러 투덜댄다로 만들었어요 ㅎ

유저레벨에서 강제 리부팅



커널에선 강제 리부팅 할 수 있는 방법이 참 많은데
유저에선 방법을 찾기가 참 쉽지 않죠 -_-;
기껏해야 ExitWindowsEx 정도?

얼마전에 고민을 해보다가 한번 이런 방법은 어떨지 생각해봤습니다.
윈도우 중요프로세스를 날려버리는거죠.
안 돌아가는 머리로 끙끙대다가 생각난 개꽁수인데
해보니 잘 먹히네요 ㅎㅎ

즉, csrss.exe 같은넘을 터미네이트 시켜버리면 아주 멋지게 리붓이 됩니다 :)
그런데 csrss.exe 는 시스템 권한이 필요하므로 일반 어드민도 건들 수가 없죠?
(작업관리자로 터미네이트 해보신분들, "중대한 프로세스니 건들지마 ㅅㅂ" 라는 메시지 보셨을겁니다)

따라서 이넘을 조지고 싶으면 SeDebugPriviledge 권한을 얻어야 합니다.
그넘을 얻은후 가볍게 터미네잇! 하시면 윈도 바탕화면이 없어지고 아름다운 검은화면으로
부팅됩니다. :)

한번 해보겠습니다.

먼저 SeDebugPriviledge 권한을 얻는 코드입니다.
다른 권한을 얻을때도 사용되는 코드라 모듈화된것으로 붙혀놨습니다.
인자로는 SE_DEBUG_NAME 혹은 "SeDebugPriviledge" 을 주시면 됩니다.

#define SE_DEBUG_NAME   _TEXT("SeDebugPriviledge"); 로 전처리 되어있으니까요.





이제 저 함수를 초반에 한번 불러주시고 csrss.exe 를 터미네이트 시키시면 되겠죠.




어차피 리붓시킬 코드니 if (hPsApi) ... 따위의 검사 루틴은 사용하지 않았씁니다.
그리고 csrss.exe를 찾는모습을 되도록이면 공개하고 싶지 않아서, 프로세스 리스트의 
배열순서를 감안하여 csrss.exe 위치인 dwProcesses[3] 이라는 쌍무식한 짓을 했습니다.

한번 해보세요.
PC가 맛탱이 가는거는 책임 못지니 버철PC등에서 하시면 좋겠습니다 :)


window31. 2008년 9월
Posted by window31


댓글을 달아주세요

  1. 2008.10.16 21:10 신고
    댓글 주소 수정/삭제 댓글
    저희 집에서는 UNKNOWN_HARD_ERROR 블루스크린이 발생하더군요.
  2. 2010.03.03 18:14 신고
    댓글 주소 수정/삭제 댓글
    병탁씨 잘쓸께용...
    오늘 딱 이게 필요한... ㅋㅋㅋ~
  3. 2010.03.16 18:52 신고
    댓글 주소 수정/삭제 댓글
    csrss 꺼도 몇 초간 제대로 돌아가는 제 컴퓨터는 뭘까요... ㄷㄷ

    또한 wininit.exe 같은 경우 끄면 즉각 블루스크린이 뜨네요. ㅋ

이번달 산 책 두권.

 | C, C++
2008.03.07 01:05

이번달 산 책 두권.



사용자 삽입 이미지


먼저 "루아를 이용한 민첩하고 효과적인 게임 개발" 입니다.

루아 스크립트 많이 아실겁니다. 와우를 위시하여 수많은 온라인 게임에서 UI 처리 등의
국가대표급 스크립트로 사용되고 있죠.

제가 게임 스크립트를 짤 일은 거의 없지만, 다른 업무적 목적으로 게임 스크립트도 쪼매 건드릴
일이 종종 있기도 하고, 예전 시큐어 코딩 교육 이후에 기획자를 위한 스크립트 보안 교육도
해달라는 요청이 있어서, 일단 그런걸 해줄마음은 전혀 없지만 어디 바이블 같은거 한번 제대로
읽어보기라도 해볼까 싶은마음에 질러봤습니다.

"Programming in Lua"와 이 책 중에 뭐를 살까 고민을 했는데,
오늘 책을 보고나니 "Programming in Lua"를 살걸 하는 후회가 드는군요 -_-

저는 머 사실 스크립트 구현에서의 크리티컬한 부분까지는 관심이 없습니다.
C/C++과 연동할 때의 취약점이나 기타 UI 해킹의 힌트가 될만한 부분이 있나 싶어서 책을 산건데
머 겜 만들때 스크립트 짜는 방법 등에 대한 얘기가 전부군요, 연동 얘기는 앞부분과 뒷부분에만
살짝 나옵니다. -_-

책도 좀 수준이 애매 모호 하네요.
개발자가 보기엔 넘 쉬운 내용을 발기발기 풀어헤쳐놓았고
코딩 못 하시는 기획자 분들이 보기에는 좀 어렵겠다 싶은 부분인데도 설렁설렁 넘어 가는군요 ;
머 그나마 맘에드는건 류광아저씨가 번역한거라 한국 책 처럼 문장은 참 읽기 편하다는거.

뭐 어쨌든 C/C++ 좀 하시는 분들은 몇시간이면 무난히 다 보실 것 같습니다.
스크립트 해킹으로 캐릭터 옷 뱃기시려는 분들 이 책 별로 도움 안됩니다. 다른 책을 고르세여.




사용자 삽입 이미지


두번째로 지른 책은 "소프트웨어 보안 검사 기술: 소프트웨어 보안 결함 식별" 입니다.
이런 책들의 상당수가 웹프로그래밍 위주의 코딩 정설론을 펼쳐대는 것이 일반적이죠.
혹시나 했는데 이 책도 역시나 네요 :p  그냥 머 혹시 건질거 있을까 해서 샀습니다.

오늘은 루아 스크립트 보느라 아직 다 보지는 못해서 머 결론은 못 내리겠지만,
어쨌든 SQL Injection 나오고  세션 공격 나오고 하는 짓으로 보아 역시 그런 책들과
크게 다를 것 같진 않습니다. 할일없는 주말에 걍 쭉 볼라구 생각중입니다.

그래도 이런거 한번도 훑어본적이 없다면 그래도 보실만 하실겁니다. 보안 이쪽 동네의 용어도
많이 접하실 수 있을거고요 :)

책꽂이를 살펴보니 맘잡고 읽으면 하루면 다 볼수있는 것을 질질 끈채 병풍처럼 처박혀있는
것들이 넘 많네요 -_- 시간 날 때마다 맘을 꼭 잡아야 겠습니다 :p


2008년 3월.


Posted by window31


댓글을 달아주세요

  1. 2008.03.07 09:55 신고
    댓글 주소 수정/삭제 댓글
    저도 이 책들 두권 다 사서 봤습니다.
    Lua 책은 대충 훓어보고 말았죠. 말씀하신 것처럼 좀 애매하더군요. -_-;;
    차라리 Programming in Lua 를 볼껄 .. 하고 후회했죠. ㅋㅋ
    (나중에 알게된 건데 Programming in Lua 번역하신 분 - redwiki 주인 - 이 Webzen 중국 지사에 계시더군요. 출장 가서 만나뵙고 왔었죠. ㅋㅋ)

    소프트웨어 보안 검사 기술.. 이책은 SDL 에 관련된 내용을 좀 보려고 했는데 약간(?) 빈약한 느낌이 없지 않아 있더군요. 해킹 기술에 대해서도 그닥 깊이 있는 내용은 없고요. (주관적인 견해이긴 합니다만.. )

    뭐 아무래도 안읽은 것보다는 도움이 될 테니... ^^
    • 2008.03.08 00:34 신고
      댓글 주소 수정/삭제
      아 여쭤보고 살 걸 그랬네요 ㅎㅎ
      역시 시스템 프로그래머라도 겜 회사에 계셨던 분이라 겜 플밍 쪽도 잘 아시는군요 ^^
      소프트웨어 보안 검사 기술...이것도 머 안전한 코딩을 위한 어쩌구 그런책들과 비슷할거라
      생각은 했는데요. 그래도 이번에 나온 책이라 뭔가 혹시 다를까 싶어서 사봤습니다 ㅎ
      미리 말씀주신 부분 감사 드립니다 ^^

Win2000 이상에서 사용 가능한 API



상용 소프트웨어 개발을 하실때 MSDN을 보다 보면 "아 이런 훌륭한 API가 있었군 써먹어야지 !"
했다가도 "아 ㅅㅂ 2K 이상만 혹은 XP이상만 되잖아 -_-" 하며 넘어간 경우가 있으실 겁니다 :p
예를들어 GetModuleFileNameEx나 OpenThread 따위의 API들이 그 예가 되겠습니다.

온라인 MSDN에 그런 API 목록을 정리해둔 사이트가 있네요.

Functions by Release
http://msdn2.microsoft.com/en-us/library/aa383687(VS.85).aspx

The following functions were added to the Windows application programming interface (API) in this release


Windows 2000 이상

more..


Windows XP 이상

more..



Windows 2003 이상

more..



다 정리하려다가, url 이 있는데 웬 삽질이지 하는 생각이 들어 걍 하다 접습니다 ㅋ
사이트를 직접 들어가셔서 확인해보세요 :)

아마 개발자분들이 직접 구현해놓은 함수들이 XP이상 혹은 2003이상에서 제공되는 API에는
포함되어 있을수도 있습니다. :p

Posted by window31


댓글을 달아주세요

  1. 2008.01.22 12:03 신고
    댓글 주소 수정/삭제 댓글
    운영체제별 NT Native API 지원 여부를 정리해 둔 곳도 있습니다
    http://jedi-apilib.sourceforge.net/native/NativeList.html
    • 2008.01.22 17:37 신고
      댓글 주소 수정/삭제
      와우! naitve는 여기 모여 있었군요
      감사합니다~
  2. 2008.01.25 16:01 신고
    댓글 주소 수정/삭제 댓글
    좋은 정보 감사합니다.

BLOG main image
by window31

카테고리

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

글 보관함