지뢰찾기 핵 - code injection sample 시스템 프로그래밍

http://powerhacker.net/forums/viewtopic.php?t=51
지뢰찾기 프로그램 핵을 만드는 예제가 있더군요.  D2HackIt 을 통해서 훅을 하는 예제였습니다.

winmine.exe 를 IDA 로 열어보니 심볼서버에 winmine.exe 에 대한 심볼들이 있더군요. 호호. 놀랬습니다.

디버깅심볼이 있어서 ShowBomb() 함수가 바로 보이더군요.
저 문서를 작성한 분도 ShowBomb() 함수를 호출하는 방법을 사용했습니다.
 
오늘 오후에 시간도 좀 나고 .. 심심해서 다른 방법으로 같은 핵을 만들어 보았습니다.
저는 dll 을 사용하지 않고, 후킹을 하지도 않습니다.
winmine.exe 프로세스에서 직접 ShowBomb() 를 호출하는 코드를 삽입하는 방법을 사용했습니다.
오래전부터 바이러스나 웜에 자주 사용되던 기법이죠.
code injection 또는 Thread injection 이라고 하죠.

조금만 응용하면 여러 방면에 아주~~ 유용하게 써먹을 수 있답니다. 패커, 바이러스, 스텔스 웜.. 등등.. :-)
아래에 있는 코드로는 음.. 한 2% 부족할겁니다. 하지만 조금만 생각해 보면 해결할 수 있을겁니다.

somma_winmine_hack.zip
참고로 이 프로그램은 win 98 에서는 안됩니다.
지뢰찾기 프로그램(winmine.exe -  windows xp 에 포함되어있는..)을 실행하고, 작업관리자 같은 툴을 통해 process id 를 알아내서 Showbomb.exe 에 입력하면 됩니다.  :-)





/** ---------------------------------------------------------------------------
\brief

\param
\return
\code
\endcode
-----------------------------------------------------------------------------*/
int inject_remote(DWORD dwPid)
{
if (0 != EnableDebugPriv())
{
_ASSERTE(!"oops!");
return -1;
}

// open process for inject
//
HANDLE hProc = OpenProcess(
PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |
PROCESS_VM_WRITE | PROCESS_VM_READ,
FALSE,
dwPid);
if (hProc == NULL)
{
_ASSERTE(!"OpenProcess");
return -1;
}


DWORD_PTR funcBody = GetFunctionRVA(injetor_stub);
int proc_size = SizeOfProc(funcBody) + 1;
if (1 == proc_size)
{
_ASSERTE(!"proc_size");

CloseHandle(hProc); hProc = NULL;
return -1;
}

// step #1

// step #2
// allocate buffer for thread procedure
//
char* proc_buf = (char *) VirtualAllocEx( hProc,
0,
proc_size,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (NULL == proc_buf)
{
_ASSERTE(!"proc_buf");
CloseHandle(hProc); hProc = NULL;
return -1;
}

// step #3
//

// step #4
//
DWORD dwBytesWritten = 0;
if (0 == WriteProcessMemory(hProc,
proc_buf,
(char *)funcBody,
proc_size,
&dwBytesWritten))
{
_ASSERTE(!"writeprcsmemory");

VirtualFreeEx(hProc, proc_buf, proc_size, MEM_RELEASE);
proc_buf = NULL;

CloseHandle(hProc); hProc = NULL;
return -1;
}


// 자~ 시작해 볼까나?
//
DWORD dwTid = 0;
HANDLE hThread = CreateRemoteThread( hProc,
NULL,
0,
(LPTHREAD_START_ROUTINE)proc_buf,
NULL,
CREATE_SUSPENDED,
&dwTid);
if (NULL == hThread)
{
_ASSERTE(!"hTherad");

VirtualFreeEx(hProc, proc_buf, proc_size, MEM_RELEASE);
CloseHandle(hProc); hProc = NULL;
return -1;
}

ResumeThread(hThread);

WaitForSingleObject(hThread, INFINITE);

CloseHandle(hThread); hThread = NULL;
VirtualFreeEx(hProc, proc_buf, proc_size, MEM_RELEASE);
proc_buf = NULL;

CloseHandle(hProc); hProc = NULL;

return 0;
}



/** ---------------------------------------------------------------------------
\brief thread procedure to be injected

\param
\return
\code
\endcode
-----------------------------------------------------------------------------*/
__declspec( naked )
DWORD __stdcall injetor_stub(void* pBlock)
{
__asm /* prolog */
{
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE
}


// 지뢰를 보여주셈~~
//
__asm
{
mov eax, 0x0A
push eax
;call [0x01002f80]
mov eax, 0x01002F80
call eax
}


//-------------------------------------------------------------------------

__asm /* epilog */
{
xor eax, eax // always return 0 (33 C0)
mov esp, ebp
pop ebp

/* epilog signature */
xor eax, eax
xor eax, eax

ret 4 // 0xC3
}
}

덧글

  • 모지 2007/01/08 11:01 # 삭제 답글

    지뢰찻기갓은 쓸데엄는거 왜하3?
    지뢰찻기 지뢰 다보여주는거 울학교에서는(참고로 중1임) 개나소나 다 할줄암 ㅡㅡ; 개전니쉬움.. 인텔문서만 가지고 3시간이면 끝나는거 아녜염?
    thread, function, raw code injection은 치사한 방법이라고 기술쌤이 될수있으면 하지말라고 했는데~
    개전니 쉬운거에염 cpu교육 일주일 배우구 바루 컴퓨터실에서 실습~(참고루 과고반임)
    요세 우리반 칭구들 다들 그거에 빠져서 살그염 ㅋㅋ
    이젠 리니쥐하그 스포핵만들어서 인포마에서 팔고이씀 ㅋㅋㅋ
    사진보니 나이두 개많은 아저씨인갑다 완존옆집아저씨네
  • include 2010/05/09 00:27 # 삭제

    모지님 국정원입니다.
    cpu교육!을 일주일!! 하시고 C언어나, C#등등도 필요없이
    cpu교육!을 일주일!! 하시고 위와 같은 코딩을 개나소나 할 정도로 개 전니 쉬워하시는 분
    저희 국정원에 오십시오!!

    으잌ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
  • somma 2007/01/08 11:23 # 답글

    응.. 미안해 ..앞으론 안할께 :-)
  • yser 2007/01/16 17:39 # 답글

    모지님을 보니.. 역시 나이에 걸맞지 않는 분에 넘치는 능력을 미리 가졌을 때의 위험성..에 대해서 떠올리게 되는군요.
  • 유리바다 2007/01/16 23:33 # 답글

    모지라? 아가~ 어려운 것 좀 줄테니 해 볼려? 재밌넹.. ^^;;
  • somma 2007/01/17 10:40 # 답글

    yser , 유리바다/
    나이에 걸맞지 않게 분에 넘치는 능력을 가졌다기 보단..전 그 능력 자체가 의심스럽습니다.
    익을 수록 숙여진다는데 아직 숙여질 만큼 알고 있는 것이 없는거죠.
    단순히 팁에 가까운 기술만 알고 있거나 입만 산 케이스가 아닐까...합니다.
    cpu 교육 일주일, 인텔 문서 가지고 3시간.. 뭐 대체 말이 되는 말이 없습니다.
    하하.. 그래도 저런 친구들 자주 들려주었으면 좋겠어요. 아주~~ 재밌네요. 귀엽기도 하고..ㅋㅋ
  • nerd 2007/01/22 15:07 # 답글

    허걱... somma님 이제 초딩팬까지 ㅋㅋ
    난 언제쯤 저런 초딩팬이 생기려나 ㅡㅡ;
  • somma 2007/01/22 19:19 # 답글

    크크..요즘엔 안들어 오나봐.. 울 초딩팬.. 심심해...ㅎㅎ
  • 서우석 2007/01/23 21:49 # 삭제 답글

    안녕하세요? 우연히 방문하게 되었습니다. ^^
    이 내용은 오래전에 www.codeproject.com에서 기사가 올라왔었죠. 이거 말고도 카드 게임 해킹한것도 있습니다. (동일 인물이 올린 기사)
    블로그 내용이 재밌어서 잘 읽고 갑니다~
  • somma 2007/01/25 18:06 # 삭제 답글

    안녕하세요.
    네.. codeproject 에도 비슷한 내용이 있고.. codeguru 에도 있는걸로 기억합니다. ^^;;
    2004년 blackhat 발표자료에도 .. stealthy worm 관련 해서 문서가 있었을 겁니다... 아마도...

    저도 디버그랩이나 서우석님 블로그 자주 간답니다.
    자주 들여주세요..ㅎㅎ
  • 이철길 2007/02/01 11:43 # 삭제 답글

    injetor_stub 내부 코드좀 설명 부탁드립니다....ㅠㅜ
    어셈을 해본 적이 전혀 없어서요...
  • somma 2007/02/01 13:21 # 답글

    winmine.exe 를 리버싱해보면 0x01002f80 의 주소에 ShowBomb() 함수가
    있습니다.
    ShowBomb() 함수는 파라미터를 하나 받는데요.
    폭탄을 보여주는 경우 0x0A 를 파라미터로 넘겨서 호출하더군요.
    아래의 코드는 0x0A 를 파라미터로 넘겨서 0x01002f80 에 있는 ShowBomb()
    함수를 호출하는 것입니다.
    더 궁금한거 있음 아는데 까지 도와드릴께여..ㅎㅎ
    __asm
    {
    mov eax, 0x0A
    push eax
    ;call [0x01002f80]
    mov eax, 0x01002F80
    call eax
    }
  • 이철길 2007/02/02 11:01 # 삭제 답글

    답변 감사합니다...^^
    한가지만 더 물어 보겠습니다.. 죄송...
    ShowBomb() 이 0x01002f80 주소지에 있다는 것을 어떻게 알수 있나요??
    실행할때 컴퓨터 마다 주소지가 다를것 같은데요...
    간단한 답변 부탁드립니다...
  • somma 2007/02/02 11:39 # 답글

    죄송하긴요 ^^
    dll 의 경우는 시작 주소에 다른 dll 이 먼저 로딩되는 상황이 발생할 수 있습니다. dll 은 실행되는 프로세스의 주소공간에 매핑되는 녀석이기 때문이지요. 그래서 system dll 들을 보면 파일 이름에 따라서 기준 주소를 설정하는 규칙이 있어서 system dll 들끼리는 같은 기준 주소에 로드되는 일을 피하도록 만듭니다.
    아무튼 dll 의 경우 기본으로 (VS 기본 설정) 0x10000000 인가요.. 그 주소에 로딩되게 되어있는데 이미 다른 녀석이 그 주소에 로딩된 경우 loader 가 다른 사용가능한 주소로 옮겨 버립니다. 문제는 기준 주소가 바뀌면 jmp [base_address + offset] 형태로 호출되는 많은 코드들이 오류가 나겠죠. 그래서 PE 에 보면 relocation 섹션이 있는 것이구요.
    그러나 exe 의 경우 동일한 주소공간을 다른 process 가 먼저 점유하는 일이 발생할 수 없습니다.
    실행되면서 4 G 의 가상 주소공간을 운영체제가 만들어 주기 때문이지요.
    결국 ShowBomb() 라는 함수의 주소(가상 주소죠..)는 항상 동일합니다. :-)
  • 이철길 2007/02/02 15:21 # 삭제 답글

    아^^ 그렇군요...
    넘넘 감사합니다... 아직 학생이라서 모르는게 너무 많네요...
    열심히 공부할께요.. 오늘도 즐겁고 행복한 하루 되시구요....^^
  • AmesianX 2007/02/04 14:47 # 삭제 답글

    모지라는 초딩은 somma 님의 스킬이 많이 샘났나 보네요..
    ㅎㅎㅎ
    그래도 어디서 줏어들은건 있어서 쯧쯧..

    ========================================================
    (모지)초딩에게 한마디..
    somma 님이 쓰는 기술은 그냥 코드인젝션이 아니란다..
    쯧쯧..
    눈을 뜨거라.. 어린해커여..
    ========================================================
  • somma 2007/02/05 09:33 # 답글

    AmesianX / ^^
  • yskim0383 2007/04/28 17:40 # 삭제 답글

    져도모르는 사실입니다. 혼자안다고 입나불나불걸지마세요?
  • yskim0383 2007/04/28 17:44 # 삭제 답글

    바른말 고운말 합시다!
  • yskim0383 2007/04/28 17:44 # 삭제 답글

    복이와여
  • yskim0383 2007/04/28 17:45 # 삭제 답글

    모르면 잘가르쳐 주고요?
  • yskim0383 2007/04/28 17:48 # 삭제 답글

    아 somma너말이였구나?
  • yskim0383 2007/04/28 17:48 # 삭제 답글

    죄송
  • somma 2007/04/30 10:56 # 답글

    yskim0383 / 뭔소린지.. -_-;;
  • 왕눈이 2007/06/25 19:01 # 삭제 답글

    저위에 모지 초딩인지 또라인지를 보며 생각나는 요새 막말로 애새끼들...
    기술적으로는 참 뛰어난 핏덩이 종자들이 있음은 틀림없는 사실입니다.
    전통적 컴퓨터아키텍쳐들을 어디서 주서들었는지는 몰라도 상당한 수준인것만은 틀림이 없구요..
    제가 본 핏덩이들은 바이러스 소스 어디서 베낀건지, 이것저것 아류작을 만들어내는 것들이었죠.
    (그런 핏덩이들과 어찌어찌 해서 한동안 같이 있어봤다는.. ㅡㅡ;)
    사회생활 빵점
    팀웍 개판
    커뮤니케이션 --> '에헤라 이 수박씨발라먹을"
    하여간 왠지 인간 말종을 보는듯한 인상이라 앞으로도 지워버릴 수가 없군요...
    저런 애들은 제발 게시판에 글만 올리고 밖으로는 나돌아다니지 말길.

    사회나 개인적으로나 학교나 종교활동에서 다시는 만날 일 없으면 좋겠습니다!!!!
  • somma 2007/06/26 17:34 # 답글

    왕눈이 / 호되게 당한 적이 있으신가 보네요. ^^
  • 1234 2007/07/28 20:42 # 삭제 답글

    혹시 소스코드 있으시면 주실수 있나요???
  • somma 2007/07/29 21:46 # 삭제 답글

    1234 / 소스 코드는 위에 본문에 있는게 거의 다입니다. 코드는 지금 어딨나 모르겠네요. ^^
  • ZIGBEE 2007/08/11 10:25 # 답글

    재미있겠다.. 좋은 포스트 감사해요! ㅋ
  • somma 2007/08/11 12:28 # 삭제 답글

    ZIGBEE / ^^; 별말씀을요
  • 파괴의광학 2008/06/22 23:04 # 삭제 답글

    요즘엔 초딩들도.. ㄷㄷㄷㄷㄷ 쩝니다 쩔어요...
  • somma 2008/06/27 14:34 # 삭제

    초딩들도 무섭죠. (인터넷을 장악한건 초딩이라는 .. )

    전에 보안 컨퍼런스에 간적이 있는데 초등학생으로 보이는 작은 친구가 열심히 발표를 듣고 있는게 보이더군요.
    그런 친구들이 제 나이가 되면 어떨지...흐흐..
  • 2008/07/20 23:55 # 답글 비공개

    비공개 덧글입니다.
  • somma 2008/11/18 05:50 #

    프리차일드 / 헉.. 댓글이 있는줄도 몰랐네요. -_-;;
    다시 댓글 달아주세요~ ㅋㅋ
  • canelia 2008/11/29 15:07 # 삭제 답글

    오랫만이에요.ㅎㅎ 제대했더니 시간이 좀 많네여 ㅎㅎㅎ
    1개의 매개변수에 0x01002FDD 에 retn 4 가 있네요

    CreateRemoteThread(..., (LPTHREAD_START_ROUTINE)0x01002F80, (LPVOID)0x0A, ...);

    이렇게 해주는 것도 방법이 될 것 같네요 ㅎㅎ
  • somma 2008/12/02 21:20 # 삭제

    오오.. 제대하셨나보군요. 축하드립니다.

    말씀해 주신 방법이 더 멋진데요 !!
  • NeNa 2010/02/26 16:55 # 삭제 답글

    잘 보고갑니다~ code injection 연습하고잇는데 상당히 재밋는 기술이네요.
  • include 2010/05/09 00:22 # 삭제 답글

    모지<< 이 초딩에게 한마디 하고 싶네요.
    도대체
    cpu 교육 받아서 뭐하는거죠?으잌ㅋㅋ

    최소 C언어라고나 했으면.. 아무말이라도 안하겠네요 ㅋㅋㅋㅋㅋㅋ CPU공부하면 요즘은 개나소나 프로그램이 뚝딱 되나봅니다 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
    어이쿠야.. 저런놈들 덕분에 앞으로 디버깅은 할일이 없겠네욬ㅋㅋㅋㅋ
  • include 2010/05/09 00:25 # 삭제 답글

    이런놈들 있는데 왜 그 비싼 돈을 알파테스트하고 이짓하는지 참ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
    에휴..

    "모지" 초딩팬분 ~

    다 필요없고 char* 이게 뭔지 설명좀 해주세요 ㅠㅠㅠㅠ
    CPU... 아 진짜 제대로 뿜고가네요 ㅋㅋㅋㅋㅋㅋㅋㅋㅋ
  • 2010/06/02 16:30 # 삭제 답글 비공개

    비공개 덧글입니다.
  • somma 2010/06/02 22:16 #

    inject_remote() 함수가 injetor_stub() 함수의 코드를 타겟 프로세스에 끼워넣는 함수입니다.
  • dojuha 2010/06/02 16:31 # 삭제 답글

    저게 비정상함수를 호출하는 기법이죠?(아닌감?)
  • somma 2010/06/02 22:17 #

    비정상함수를 호출하는 기법(?) 이 뭔지 제가 잘 모르겠네요. ^^;
    그냥 dll 만들어서 injection 하기 귀찮아서 코드 자체를 끼워넣어서 필요한 내부 함수를 호출한 것일 뿐입니다.
  • Hazelnut 2014/08/06 11:06 # 삭제 답글

    성지순례 왔습니다 ㅋㅋㅋㅋㅋ
  • 123 2015/02/16 19:56 # 삭제 답글

    성지순례 왓습니다 -ㅅㄷㅇ-
  • GrayField 2016/02/11 14:37 # 삭제 답글

    성지순례 왔습니다. ㅎㅎ 귀여운 모지 지금은 23살이 되었겠네요.
  • 423 2016/11/04 14:39 # 삭제 답글

    모지 ㅋㅋㅋㅋㅋ

    저거 그냥 딱봐도 재밌자고 한말같음..
댓글 입력 영역