외규장각 도서 환수 모금 캠페인

Search Results for 'Study/Computer Science'

60 POSTS

  1. 2007.06.07 상대경로에서 절대경로 계산하기 2
  2. 2007.06.06 객체지향 이야기 - 전병선
  3. 2007.06.01 Thread 해결 ^____________________^ 2
  4. 2007.06.01 쓰레드 ㅠ_ㅡ 2
  5. 2007.05.31 오늘의 샘플 분석 ㅠ_-

void Symbut::GetAbsolutePath()
{
 char szBackup[200] = "";
 char szCurrentPath[200] = "";
 char drive[10] = "";
 char dir[100] = "";
 char fname[50] = "";
 char ext[10] = "";

 GetCurrentDirectory(200, szBackup);  // 현재의 경로를 백업
_splitpath((LPCSTR)(LPCTSTR)szWorkFolder, drive, dir, fname, ext);

 if (isalpha(dir[0])) // do not need to transform
  return;
 else
 {
  while (szWorkFolder.Find("..") == 0)
  {
   _chdir("..");
   szWorkFolder.TrimLeft("..");
  }

  while (szWorkFolder.Find(".") == 0)
  {
   _chdir(".");
   szWorkFolder.TrimLeft(".");
  }
  GetCurrentDirectory(200, szCurrentPath);
  SetCurrentDirectory(szBackup);
  szWorkFolder = szCurrentPath + szWorkFolder;  
 }
}


_chdir 함수를 쓰면 현재 작업 디렉토리(Working Directory)를 변경시켜준다. 즉, 파라미터로 넘겨준 값을 가지고 cmd 창에서  cd "파라미터" 한 것과 같은 효과를 낼 수 있다.

그래서 입력 받은 상대 경로를 절대 경로로 변경하기 위해서 .. 의 수만큼 _chdir을 호출하여 작업 경로를 변경시킨 후에 GetCurrentDirectory()  함수를 호출하여 작업 경로를 얻어오고 ..을 제외한 나머지 경로를 뒤에 덧붙이는 식으로 절대 경로를 만들 수 있다.

그런데 이러한 과정에서 작업 경로가 바뀌면 프로그램의 다른 부분에서 작업경로에 기준하여 참조하는 다른 파일이( ini 파일과 같은) 있을 경우에 해당 파일을 찾을 수 없다는 에러를 발생 시키게 된다. 따라서 작업 경로를 변경하며 절대경로를 얻어오기 전에 미리 현재의 작업 경로를 저장해두었다가 나중에 다시 가져오는 방법을 사용했다.

GetCurrentDirectory() 함수는 이처럼 현재의 작업 경로를 얻어오는 함수인데, 작업 경로는 기본적으로 실행파일이 위치하고 있는 경로이지만 별도로 설정해 줄 수 있기 때문에 (SetCurrentPath 함수, 혹은 _chdir 함수 등을 이용) 현재 실행되고 있는 파일의 경로를 정확하게 얻어오기 위해서는 GetModuleFileName함수를 사용하는 것이 좋다고 한다. (이승희 주임님 말씀 ㅋ)

그리하여 함 해볼려그랬더니 GetModuleFileName은 모듈의 핸들값을 받아가야되는거다.
경로 얻어올려고 별로도 핸들 구해서 하기도 그렇고 해서 그냥 썼다 -_-;

결과적으로 어떻게 되긴 되는데 뭔가 굉장히 깔끔한 방법이 없나..
이놈의 심벗뜨는 언제쯤 제대로 돌아가려나 ㅋㅋ
Response : ,

객체지향 이야기 - 전병선

Posted 2007. 6. 6. 12:26, Filed under: Study/Computer Science

지난 주부터 빌려보고 있는 책.

1~9장 까지는 객체지향의 개념과 각 언어별 구현, 특징이 문법적인 설명보다는 개념 설명에 중점을 두고 쓰여져 있음.

특정 프로시저(함수) 단위로 프로그램을 나누어서 작성하는 방식이 아니라
[연산 + 데이터] 를 하나의 객체 단위로 보고, 이러한 객체 프로그램을 작성하는 것.
프로그램의 진행은 객체들간의 데이터와 행위(behavior)의 통신으로 이루어짐.
객체들 사이의 데이터 처리의 흐름을 분석하고 설계하는 것이 그만큼 중요하다.

언어의 문법적인 특징보다는 객체지향적 사고 방식으로 프로그램을 작성하는 것이 포인트!

구조적 방법은 (프로시저 단위로) Divide and Conquer 방식을 목표로 소프트웨어 시스템을 세부적인 것으로 나누어 작성하므로 전체를 잘못 이해하면 세부적인 것도 잘못 이해되어 소프트웨어 전체가 잘못된 구조를 갖기 쉽다. 그러나 처음부터 전체를 제대로 이해하는 경우는 매우 드물기 때문에 전체에서 세부적인 것까지 제대로 분석되기 설계되기 전까지는 그 다음 과정을 진행하기 어렵다.

객체지향적 방법은 하나의 소프트웨어 시스템을 여러개의 객체로 구성된 것으로 본다. 각 객체는 독립적으로 고유한 기능과 서비스를 제공하며. 전체 소프트웨어 시스템을 구성하는 하나의 논리적인 구성요소가 된다. 따라서 해당 객체의 기능을 독립적으로 향상 시킬 수도 있고 다른 소프트웨어 시스템에도 재사용할 수 있으며, 또 사용자의 요구사항이 변경된 경우에도 유연하게 대응할 수 있다는 이점이 있다.


추상화 : 어떤 사물에서 필요한 데이터와 연산만을 뽑아서 객체화 하는것

캡슐화
: 내부 데이터 구조나 구햔 방법을 감추고 인터페이스만을 공개.
           필요에 따라 내부 데이터 구조나 구현 방법을 자유롭게 변경할 수 있음.

모듈성 : 크고 복잡한 것을 좀 더 작고 관리하기 쉬운 조각으로 나누어 이들 조각을 독립적으로 개발할 수 있는 특성

상속성 : 객체들 사이의 계층 관계에 따라 상속을 통하여 재사용성을 높이고 쉽게 구현할 수 있음

다형성 : 상속성을 통해서 구현 가능한, 동일한 메세지에 대해서 객체에 따라 서로 다른 연산을 수행하는 특성.

이런 것들에 대해서 대표적인 객체지향 언어에서 어떤 식으로 구현되는 지를 설명.

또한  C++, C#, JAVA,VB.NET 등 특정 언어에서  객체지향을 구현하기 위한 여러가지 기능을 제공하고 있는데 단순히 문법에 대한 이해보다는 이런 기능을 어떻게 활용하여 객체지향이라는 패러다임을 구현하는 지가 중요하다는 것,

 
어떤 기능이 있고 없고 어떤 언어가 더 우월한지, 더 객체지향적인지 판단하는 것은 의미가 없고, 이러한 기능들이 오버헤드로 작용할 수도 있기 때문에 필요한 때에 적절히 사용하는 판단력과 지혜가 필요하다는 것을 강조하고 있다.

객체지향 언어라는 것은 객체지향 개념을 구현할 수 있는 언어.
언어 자체도 중요하지만 객체지향 개념을 잘 적용하여 설계한다는 것에 뽀인트!

너무 자세한 설명 탓에 약간 지루한 감이 있지만 재밌다.
 


Response : ,

Thread 해결 ^____________________^

Posted 2007. 6. 1. 13:08, Filed under: Study/Computer Science

어제부터 고민하던 문제 완죤 해결 ㅋㅋㅋ

OK 버튼 눌렀을 때 실행하는 모든 프로시저를 스레드로 만들면 순차실행하는 데 아무런 문제 없음
전에 이런 방식으로 할려다가 Dialog Item 들을 마음대로 사용할 수 없어서 포기했는데 (5번 문제점)

CWnd를 상속한 클래스에서 멤버 함수로 핸들을 가지고 있으니까 이걸 써두 되고..
The m_hWnd data member is a public variable of type HWND

윈도우를 통째로 스레드 프로시저의 파라미터로 넘겨서 캐스팅하면 OnOK 함수 내에서 처럼 사용 가능하다는 것 ^^ .. 다른 맴버 변수에 직접 접근할 수 있기 때문에 이 방법이 더 깔끔하다.

스레드 첨 써봐서 진짜 힘들었는데.. 그럭저럭 인제 어째 되는지는 알겠다.
이번 경우는 스레드간 통신도 없고 동기화도 안해도 되는 별로 어렵지 않은.. 단지 스레드였지만
다음에는 더 어려운거에 도전해봐야지 ㅋㄷ

UINT threadCnt(LPVOID DlgHpcnt)
{
 // create class instances
 CHpCntDlg* Cntdlg = (CHpCntDlg*)DlgHpcnt;   // 이렇게 캐스팅해서 맘껏 사용 ㅋㄷ
 HpCounter* hpc = new HpCounter(Cntdlg);
 
 // disable button
 Cntdlg->GetDlgItem(IDOK)->EnableWindow(false);

 // Homepage upload count
 hpc->MakeTmp();   // make temporary folder
 Cntdlg->GetDlgItem(IDC_STEP)->SetWindowText("홈페이지 업로드 카운트 중...");

 if(Cntdlg->m_CheckINI ==TRUE) {
  hpc->WriteINICnt();
 }

 // Sample Count
 Cntdlg->GetDlgItem(IDC_STEP)->SetWindowText("엔진 샘플 수 카운트 중...");
 SpCounter* spc = new SpCounter(Cntdlg);
 for(int i = 0; i < 7; i++)
 {
  spc->TotalSample();
  spc->ECSample();
  spc->MoveDate();
 }
 
 CTimeSpan day = CTimeSpan(1,0,0,0);
 CTime Date = CTime::GetCurrentTime() - day;

 CString szBuffer = _T("");
 char szBuf[80] = _T("");


 
 // Print Result
 Cntdlg->m_Result.DeleteAllItems();
 Cntdlg->GetDlgItem(IDC_STEP)->SetWindowText("결과 출력");
 for (i = 0; i < 7; i++){
  szBuffer.Format("%8d.%02d.%2d", Date.GetYear(), Date.GetMonth(), Date.GetDay());
  Cntdlg->m_Result.InsertItem(LVIF_TEXT, 0, szBuffer, 0, 0, 0, 0);
 
   itoa((spc->arResult[6-i]).nTotalSample, szBuf, 10);
   Cntdlg->m_Result.SetItemText(0, 1, szBuf);

   
   itoa((spc->arResult[6-i]).nECSample, szBuf, 10);
   Cntdlg->m_Result.SetItemText(0, 2, szBuf);

   
   
   itoa((hpc->arResult[6-i]).nKorCnt, szBuf, 10);
   Cntdlg->m_Result.SetItemText(0, 3, szBuf);
   
   itoa((hpc->arResult[6-i]).nEngCnt, szBuf, 10);
   Cntdlg->m_Result.SetItemText(0, 4, szBuf);
   
  Date -= day;

 }
 //enable Run button
 Cntdlg->GetDlgItem(IDOK)->EnableWindow(true);
 
 return 0;
}

Response : ,

쓰레드 ㅠ_ㅡ

Posted 2007. 6. 1. 11:58, Filed under: Study/Computer Science

void CHpCntDlg::OnOK() {
 
UpdateData(TRUE);
HpCounter* hpc = new HpCounter(dlg);
 
 // Homepage upload count
 hpc->MakeTmp();   // make temporary folder
 GetDlgItem(hWnd ,IDC_STEP)->SetWindowText("홈페이지 업로드 카운트 중...");

 pHpthread = AfxBeginThread(threadHompageCnt, hpc);

 if( m_CheckINI == TRUE){
  hpc->WriteINICnt();
 }

 // Sample Count
 GetDlgItem(IDC_STEP)->SetWindowText("엔진 샘플 수 카운트 중...");
 SpCounter* spc = new SpCounter(this);
 pSptread = AfxBeginThread(threadSampleCnt, spc);
 pSptread->SuspendThread();

...

}

------

1. Ok 버튼을 눌렀을 때 수행되는 위의 프로시져가 웹페이지를 다운로드해서 파싱하고 결과를
   출력하는 시간이 꽤 걸리는 작업이라서 창을 다시 그려줄  때 깨지거나 응답없음이 나타난다.

2. 쓰레드를 이용해서 내부 프로시져가 돌아가는 거랑 창을 그려주는 걸 별도로 수행하도록 하면
    해결할 수 있음.

3. 쓰레드를 생성하기 위해서는 UINT 함수이름(LPVOID pParam); 와 같은 형식의 쓰레드에서
   실행하는 처리를 당담하는 프로시저가 필요함
   (형식의 제한이 있어서 복잡한 파라미터를 넘겨주는 함수를 구현할 수가 없었다.
    이럴 때는 파라미터를 모두 가지는 구조체를 선언하여 그 포인터를 넘기면 된다고 한다.)

4.  쓰레드를 생성할 때는 CreateThread 윈도우 API 보다는 AfxBeginThread를 사용하는 것이 바람직
C/C++의 표준 라이브러리를 사용하는 경우 프로세스 내의 스레드는 메모리 공간을 공유하기 때문에 정적 변수 사용등에 있어서 문제가 발생한다. (예: strtok) 이를 방지하기 위해서 윈도우에서 쓰레드마다 다른 메모리 영역을 정적으로 할당(TLS: Thread Local Storage) 이 때 TLS를 사용하기 위해서는 쓰레드를 생성할 때 초기화 등의 준비가 필요한데 CreateThread를 사용해 쓰레드를 생성하면 이런 처리를 할 수 없다.

5. 쓰레드 함수 내에서는 GetDlgItem() 함수를 호출할 수 없음. (쓰레드 함수는 전역으로 선언되어있고 윈도우(다이얼로그) 내부의 함수가 아니므로) 그리하여 GetDlgItem 부분은 OnOK() 함수에서 처리하고 나머지를 둘로 나누어 각각 쓰레드로 처리하려고 했는데.. 그렇게 했더니 파일 I/O 가 있는 부분에서 대기하는 동안 제어가 다른 쓰레드로 넘어가면서 병렬로 처리되고 결과가 제대로 안나온다. 순차적으로 처리해야하는 프로시저에서 분리를 목적으로 쓰레드를 사용하니까 참 맘대로 안된다.

6. 그래서 WaitForSingleObject() 를 사용해서 쓰레드 처리를 기다리려고 했는데. AfxBeginThread 함수나 CreateThread 함수는 쓰레드 생성에 성공하면 쓰레드 프로시저의 종료를 기다리지 않고 즉시 호출로부터 복귀한다. 그래서 WaitForSingleObject 가 별로 소용이 없다. 게다가 메인 프로시저는 쓰레드 프로시저의 상태와 상관없이 계속해서 프로그램을 실행하므로 출력루틴이 먼저 실행되는 사태가 발생해서 완전 결과가 엉망이 됐다.

7. 윈도우 자체를 쓰레드 프로시저에 넘겨주고 GetDlgItem를 호출할 수 있도록 만들려고 했는데 윈도우 핸들을 얻어오는게 맘처럼 쉽지가 않다 ;;

8. 쓰레드 핸들을 사용해서 한번 컨트롤 해봐야겠다..

쓰레드 너무 힘들다 ㅠ_ㅠ

Response : ,

오늘의 샘플 분석 ㅠ_-

Posted 2007. 5. 31. 22:10, Filed under: Study/Computer Science
오늘 내가 분석한 악성 코드는  UPX 팩으로 실행압축되고 자체 암호화 모듈로 암호화된 다운로더.

UPX 팩의 어셈블리 패턴에 대해서 얼마전에 배웠기 때문에 실행압축을 푸는 것은 비교적 쉽게 할 수 있었지만 그 이후에 수많은 함수 콜과 스택 관리. 루프. 점프 등등 -_-

아직도 모르는게 너무 많다.
그렇지만 제대로 깨달은 건..
너무 자잘한 함수까지 내부에서 구현하는 부분까지 다 따라가면서
레지스터 값 확인하는 거는 완전 삽질이라는거-

함수 콜하나 루프하나 도는데도 완전 레지스터 값을이 엉망이되고 스택이 어지러운데
그런걸 하나하나 따라가다가는 도저히 감당이 안된다.
전혀 이해할 수가 없다.

결국 파일을 쓴다거나 레지스트리를 수정한다거나 하는 건 GetProcAddress 나 LoadLibray  같은 걸로 이미 얻어온 API  함수를 간접호출 하는 방식으로 이루어지기 때문에
악성 코드가 어떤 목적으로 어떤 상황에서 어떤 API를 호출하는지 그런걸 잘 알아보고
그런 함수들이 호출될 때 함수 파라미터가 어떤게 넘어가는지만 확인하는게 좋다는거
예를 들어 WriteFile의 파라미터가 뭔지만 알면 어떤 파일을 생성하는지 바로 알 수 있으니까..

Call 이나 Retrun 부분에만 브레이크 포인트를 걸고 체크 체크 하는게 훨씬 깔끔하다.
주요 증상만 판단하자.
너무 초반부터 깊이 파도 낭패본다 -_-

---------

게다가 결국 내가 오늘 본 파일은 다운로더를 다운받는 다운로더.
내용 자체는 그렇게 어렵지 않지만 손이 많이 가는 녀석이었고 실행 과정은 실행 압축 및 암호화로 완전 꼬여있어서 잘안보였다.

게다가 Anti Virus 프로그램 및 시스템 상태 분석 도구들을 강제로 프로세스 킬하는 기능까지 있어서
무쟈게 고생 -_-;

이상철 선임님이 오늘부터 휴가가시면서 업무 인수인계하실 때 인턴들한테 분석 좀 틈틈히 시키라고 하시고 가셨는데 (다른 정팀원들은 아직 인턴을 잘 안믿으신다) 오늘은 네명 다 고생고생,
결국 엔진 배포 때까지 분석 못한 사람은 인턴 네명 뿐..;
그래서 정말 마음이 안좋았다.
내일 가서 완전 복습하고 박살 낼꺼다. 쳇쳇..

Response : ,

« Previous : 1 : ··· : 7 : 8 : 9 : 10 : 11 : 12 : Next »

Recent Posts

Recent Comments

Recent Trackbacks

Total hit (Today , Yesterday )

Admin Write Post