2010.01.10 16:27 System


파일 구조를 공부하던 중

공부하기 좋은 문제를 발견했다

사실 발견 한지는 꽤 됐는데.. 내내 미루고 있다가 풀기로 했다

처음 파일을 보면 파일이름은 mirror.avi 고

재생해보면 다크나이트의 예고편임을 알 수 있다

예고편을 봐도 힌트 같은건 눈꼽만치도 찾아볼수도 없다

파일을 헥사 에디터로 열어보면



Base64로 인코딩된 Hint를 볼 수 있다

Decoding 해보면 .redaeHriapeR 이다

이게 뭔소린고 하니

거꾸로 뒤집어보면 RepairHeader

헤더를 고치란다

마지막에 있는 문자열들이 죄다 뒤집어져있는것 , 파일이름이 mirror 인것으로

파일을 통째로 뒤집어야 한다는 것을 유추해 낼 수 있다.

물론 무작정 뒤집는게 아니라 Header 의 format 은 유지해야 할 것이다

LISTt...strlstrh8... 부분과 끝부분이 일치하는 것을 보아하니

0x58 부분부터 뒤집는게 틀림없어 보인다

이를 토대로 간단히 소스를 짜보자

파일 입출력에 관한 함수를 사용하면 된다

뒤집는 방법에는 크게

1. 배열을 선언해놓고 파일에 필요한 데이터를 저장하고, 이를 토대로 파일을 생성하는 방법

2. 파일 포인터를 이용해 한칸씩 움직이며 원본파일에서 읽고, 목표파일에 저장하는 방법

2번째 방법으로 파일 포인터를 한칸씩 움직이면서 해봤는데 속도가 너무 느리다 =,.=

파일 포인터에 관한 함수를 찾아보면 훨씬 빠르게 하는 방법도 있겠지만..

1번 방법으로 풀기로 했다.


    7
 int main(){

    8 

    9 int size,i;

   10 char *buf_mirror,*buf_reverse;

   11 FILE *mirror, *reverse_mirror;

   12 

   13 if( (mirror = fopen("C:\\tmp\\dark knight.avi", "rb") )

   14    && (reverse_mirror = fopen("C:\\tmp\\dukhoo knight.avi", "wb"))==NULL)

   15     printf("Errrrrrrrrr\n");

   16 

   17 

   18 buf_mirror=new char[size];

   19 buf_reverse= new char[size];

   20 

   21 fseek(mirror, 1, SEEK_END);

   22 size = ftell(mirror);

   23 rewind(mirror);

   24 

   25 fread(buf_mirror,1,size,mirror);

   26 

   27 

   28 for(i=0;i<='\x57';i++)

   29  buf_reverse[i] = buf_mirror[i];

   30 

   31 while( ++i <= size)

   32     buf_reverse[ i -1 ] = buf_mirror [size-i+'\x57'];

   33 

   34 fwrite(buf_reverse,1,size,reverse_mirror);   

   35 

   36 delete buf_mirror;

   37 delete buf_reverse;

   38 

   39 }

재생해보면 배트맨 대신 윤하가 나온다

동영상 마지막에 보면 패스워드가 찍히고 이상 문제 풀이 끗





'System' 카테고리의 다른 글

What is VCP[Virtualized Code Protection]?  (0) 2010.01.29
셸 코드 작성  (0) 2010.01.17
2008 JFF 8번 문제 풀이  (0) 2010.01.10
[펌]교착 상태와 그 조건  (0) 2010.01.02
What is CALLBACK function?  (0) 2010.01.01
[펌]함수 호출규약 [Calling Convention]  (0) 2010.01.01
Posted by LinkC

2010.01.02 14:15 System


1) What is Deadlock?
교착 상태(膠着狀態, deadlock)란 두 개 이상의 작업이 서로 상대방의 작업이 끝나기 만을 기다리고 있기 때문에 결과적으로 아무것도 완료되지 못하는 상태를 가리킨다. 예를 들어 하나의 사다리가 있고, 두 명의 사람이 각각 사다리의 위쪽과 아래쪽에 있다고 가정한다. 이때 아래에 있는 사람은 위로 올라 가려고 하고, 위에 있는 사람은 아래로 내려오려고 한다면, 두 사람은 서로 상대방이 사다리에서 비켜줄 때까지 하염없이 기다리고 있을 것이고 결과적으로 아무도 사다리를 내려오거나 올라가지 못하게 되듯이, 전산학에서 교착 상태란 다중 프로그래밍 환경에서 흔히 발생할 수 있는 문제이다. 이 문제를 해결하는 일반적인 방법은 아직 없는 상태이다.

출처:위키백과


2) Condition of Deadlock

4가지 조건을 모두 만족할시 교착상태가 발생한다.
순환대기는 점유대기 조건과 비선점 조건을 만족해야 성립하므로
완전히 독립적인 것은 아니다.


상호배제(Mutual exclusion) : 프로세스들이 필요로 하는 자원에 대해 배타적인 통제권을 요구한다.

상호 배제(mutual exclusion, Mutex, 뮤텍스)는 동시 프로그래밍에서 공유 불가능한 자원의 동시 사용을 피하기 위해 사용되는 알고리즘으로, 임계 구역(critical section)으로 불리는 코드 영역에 의해 구현된다.

공유 불가능한 자원의 예로는 동시에 실행되고 있는 프로그램간의 통신에 사용되는 비트 단위의 깃발, 계수기, 등이다. 문제는 스레드가 언제라도 정지되거나 시작될 수 있다는 것이다.

예) 프로그램의 일부분이 여러 단계를 거치면서 데이터를 읽고 쓰고 있다고 하자. 그런데 예상치 못한 사건 등에 의해 다른 스레드가 동작하기 시작했다. 첫 번째의 스레드가 쓰고 있는 영역에서, 이 두 번째의 스레드가 또 다른 작업을 시작한다면, 해당 영역의 값은 부적절하며 예상할 수 없는 상태에 놓이게 된다. 게다가 두 번째의 스레드가 값을 덮어 써버리기라도 한다면, 복구 불가능한 상태로 되고 만다. 그러므로 공유 데이터를 접근하는 프로그램 내부의 이른바 임계 구역이라는 부분은 홀로 수행되도록 보호되어야 하며, 다른 스레드가 동일한 부분의 프로그램을 수행해서 동일한 공유 데이터를 접근하는 것을 막아야 한다.

단일 프로세서 시스템에서, 상호 배제를 구현하는 가장 단순한 방법은 인터럽트를 억제해서 공유 데이터가 손상되는 것을 막는 것이다. 성능에 최소한의 영향을 주기 위해 인터럽트가 발생하지 않을 명령어 집합의 수는 가능한 최소로 유지시키는 것이 좋다.


점유대기(Hold and wait) : 프로세스가 할당된 자원을 가진 상태에서 다른 자원을 기다린다.

비선점(No preemption) : 프로세스가 어떤 자원의 사용을 끝낼 때까지 그 자원을 뺐을 수 없다.

순환대기(Circular wait) : 각 프로세스는 순환적으로 다음 프로세스가 요구하는 자원을 가지고 있다.


'System' 카테고리의 다른 글

셸 코드 작성  (0) 2010.01.17
2008 JFF 8번 문제 풀이  (0) 2010.01.10
[펌]교착 상태와 그 조건  (0) 2010.01.02
What is CALLBACK function?  (0) 2010.01.01
[펌]함수 호출규약 [Calling Convention]  (0) 2010.01.01
Format String Bug  (0) 2009.12.22
Posted by LinkC

2010.01.01 00:47 System


CALLBACK 를 정의하기 전에 그 반대적 개념을 가지고 있는 System Call 의 개념을 알아보겠다.


System Call

시스템 호출(System Call)은 운영 체제가 제공하는 서비스에 대한 프로그래밍 인터페이스이다. 보통 C나 C++과 같은 고급 언어로 쓰였다. 대부분의 프로그램들은 직접 시스템 호출을 사용하기보다는 고급 API를 통해 시스템 호출에 접근한다. System call 이란, 프로그래밍 언어에서 지원하지 않는 기능에 대하여 운영체계의 루틴을 호출하여 이용하는 것을 말한다. 시스템 콜의 세 가지 기능은 다음과 같다.

1.사용자 모드에 있는 응용 프로그램이 커널의 기능을 사용할 수 있도록 하는 것.

2.시스템 콜을 부르면 사용자 모드에서 커널 모드로 바뀐다.

3.커널에서 시스템 콜을 처리하면 커널 모드에서 사용자 모드로 바뀌어 작업을 계속한다.

시스템 호출의 유형

1.프로세서 제어(process Control)

2.파일 조작(file manipulation)

3.장치 관리(Device Management)

4.정보 유지(Information maintenance)

5.통신(Communication)


출처:http://ko.wikipedia.org/wiki/%EC%8B%9C%EC%8A%A4%ED%85%9C_%ED%98%B8%EC%B6%9C




 

CALLBACK funtion


일반적으로 API 함수들은 운영체제가 제공하며 프로그램에서는 이 함수들을 호출해서 운영체제의 서비스를 받는다. 예를 들어 도스의 시스템 콜 함수를 호출하여 디스크 입출력을 받는다든가 윈도우즈의 TextOut 함수를 호출하여 문자열을 출력하도록 하는 경우가 이에 해당한다. 반면 콜백 함수는 응용 프로그램이 제공하며 운영체제가 필요할 때 호출하는 함수이다. 호출되는 방향이 거꾸로 되었기 때문에 콜백이라고 부르는 것이다. 위 예제에서 TimerProc 함수는 SetTimer에서 지정한 시간마다 운영체제에 의해 호출된다. 콜백 함수를 문장화하여 정의내린다면 "운영체제에 의해 호출되는 프로그램 내부의 함수"라고 할 수 있다.

윈도우즈에서는 이런 콜백 함수가 빈번하게 사용되고 있으므로 개념을 잘 알아두도록 하자. 타이머의 콜백 함수가 대표적이며 이 외에도 중요한 열거 함수들과 몇몇 그래픽 함수 등의 콜백 함수를 사용한다. 그보다도 가장 가까운 콜백 함수의 예는 메시지 처리 함수인 WndProc이다. 이 함수는 메시지가 발생할 때마다 윈도우즈가 호출해 주며 응용 프로그램 내부에 있지만 응용 프로그램에서 직접 이 함수를 호출하지는 않는다. 오직 운영체제만이 이 함수를 호출한다.


출처:http://winapi.co.kr/win32lec/lec4/lec4-3-4.htm


 

'System' 카테고리의 다른 글

2008 JFF 8번 문제 풀이  (0) 2010.01.10
[펌]교착 상태와 그 조건  (0) 2010.01.02
What is CALLBACK function?  (0) 2010.01.01
[펌]함수 호출규약 [Calling Convention]  (0) 2010.01.01
Format String Bug  (0) 2009.12.22
Reverse Engineering Cheat-Sheet  (0) 2009.11.30
Posted by LinkC

2010.01.01 00:00 System

출처: http://serious-code.net/moin.cgi/CallingConvention

 Calling Convention?

    함수 호출 방식(Calling Convention)이란 호출자(caller, 피호출자 함수를 호출하는 함수)와 피호출자(callee, 호출자로부터 호출되는 함수) 간에 미리 정해둔, 파라미터의 전달 순서와 사용이 끝난 후의 스택 정리에 대한 규약이라고 할 수 있다. WIN32 환경에서는 기본적으로 세 가지의 호출 방식이 존재한다.

    • Standard Call -- 파라미터들은 코드 상의 오른쪽 파라미터부터 먼저 푸쉬되고(첫번째 파라미터가 스택의 맨 위로 오게 된다는 말이다.), 피호출자(callee)가 스택을 정리한다.

 

    • CDECL or C Calling Convention -- 파라미터들은 코드 상의 오른쪽 파라미터부터 먼저 푸쉬되고(첫번째 파라미터가 스택의 맨 위로 오게 된다는 말이다.), 호출자(caller)가 스택을 정리한다.

 

    • Fast Call -- C++의 내부 구조에 익숙하다면, 멤버 함수를 호출하기 위해서는 this 포인터가 반드시 필요하다는 것을 알 것이다. 일반적으로 이 this 포인터가 스택에 최초로 푸쉬되는 파라미터다. 하지만 이 방식에서는 this 포인터를 스택에다가 푸쉬하는 게 아니라, 레지스터(ECX)에 저장한다. 파라미터들은 코드 상의 오른쪽 파라미터부터 먼저 푸쉬되고(첫번째 파라미터가 스택의 맨 위로 오게 된다는 말이다.), 피호출자(callee)가 스택을 정리한다.

 

    • Pascal Calling Convention -- 이 방식은 더 이상 사용할 수 없다. 이는 모두 Standard Call로 대체되었다. 어쨌든 원래의 Pascal Calling Convention은 파라미터를 코드 상의 왼쪽 것부터 먼저 푸쉬하고, 피호출자(callee)가 스택을 정리한다.

     <!> 결국 파라미터의 전달 순서와 스택 정리에 대한 규약이 다르므로, 다른 규약을 이용해서 만들어진 DLL 안에 있는 함수를 헤더 같은 것도 없이 동적으로 바인딩해서 사용하는 경우, 그것을 컴파일러에게 명시적으로 가르쳐줘야하는 것이다. (호출하는 측과 호출받는 쪽이 다른 Calling Convention을 사용할 수 있으므로...)



                            Calling Conventions Arguments Passing Stack Maintenance Name Decorations Notes
                            __cdecl Right -> Left 호출자가 Stack에서 인자를 제거한다. 함수 이름 앞에 _를 붙인다. Ex) _foo C/C++함수의 기본 호출 규약
                            __stdcall Right -> Left 호출된 함수가 Stack에서 인자를 제거한다. _가앞에 붙고 뒤에 @와 인자의 크기가 10진수로 붙는다. Ex) _foo@12 대부분의 System 함수가 사용. VB에서 내부함수가 사용.
                            __fastcall 첫번째 2개의 DWORD 파라미터는 ECX, EDX 레지스터 사용. 나머지는 Right->Left 호출자가 Stack에서 인자를 제거한다. @이 앞에 붙고 @과 인자의 크기가 10진수로 뒤에 붙는다. Ex) @foo@12 Intel CPU 만 사용. Borland의 Delphi 컴파일러가 사용.
                            this Right -> Left this 매개변수는 ECX 레지스터사용. 호출자가 Stack에서 인자를 제거한다. None C++클래스의 멤버 함수가 사용. COM에서 사용.
                            naked
                            Right -> Left 호출자가 Stack에서 인자를 제거한다. None VxD에서 사용. Custom Prolog 와 Epilog를 만들때 사용.


                          'System' 카테고리의 다른 글

                          [펌]교착 상태와 그 조건  (0) 2010.01.02
                          What is CALLBACK function?  (0) 2010.01.01
                          [펌]함수 호출규약 [Calling Convention]  (0) 2010.01.01
                          Format String Bug  (0) 2009.12.22
                          Reverse Engineering Cheat-Sheet  (0) 2009.11.30
                          What is SVN[Subversion]?  (0) 2009.11.14
                          Posted by LinkC

                          2009.12.22 01:13 System

                          znfh
                          올해 초 . 겨울방학때 해커스쿨 워게임 깬다고 한참 시스템 분야에 삽질할때 작성했던 자료입니다

                          동아리 내 내부 세미나에서 발표했습니다

                          지금 와서 보면 정말 허접스럽게도 작성했네요

                          그땐 이거 작성한다고 얼마나 오래 걸렸는지...

                          정말 이것저것 삽질해보고 한참 고민하고 풀어내고

                          이 과정의 연속이었던것 같습니다 :)

                          Format String bug 에 대한 개념과 어떻게 일어나는지 등을 다뤘습니다

                          좀 세련되게 수정이라도 해서 올릴까 했는데, 그냥 그때 기억도 살려볼겸!


                          'System' 카테고리의 다른 글

                          What is CALLBACK function?  (0) 2010.01.01
                          [펌]함수 호출규약 [Calling Convention]  (0) 2010.01.01
                          Format String Bug  (0) 2009.12.22
                          Reverse Engineering Cheat-Sheet  (0) 2009.11.30
                          What is SVN[Subversion]?  (0) 2009.11.14
                          어셈블리어 명령어 정리  (3) 2009.11.06
                          Posted by LinkC

                          2009.11.30 01:25 System




                          전에 올린 자료에 R.E 요약 한게 몇개 있었는데

                          이게 한눈에 보기 좋네요. 마소에서 올린 자료더군요

                          물론 영어라서 좀 아쉽긴 하지만 :)

                          파일도 첨부합니다


                          'System' 카테고리의 다른 글

                          [펌]함수 호출규약 [Calling Convention]  (0) 2010.01.01
                          Format String Bug  (0) 2009.12.22
                          Reverse Engineering Cheat-Sheet  (0) 2009.11.30
                          What is SVN[Subversion]?  (0) 2009.11.14
                          어셈블리어 명령어 정리  (3) 2009.11.06
                          플레그는 아무하고나 만나주지 않는다.  (0) 2009.11.03
                          Posted by LinkC

                          2009.11.14 15:44 System


                          SVN(subversion)?
                          SVN 은 버전 관리 시스템이며 CVS 의 단점을 보안 하기위해 만들어진 시스템입니다.
                          SVN 을 기준으로 업데이트하고 서버에 업로드하는 형식으로 사용자가 언제 어떤 부분을 수정을 했는지에 대한 모든 소스의 로그가 남고 간단히 예전 버전으로 돌리기도 가능합니다.
                          더 자세한건 위키피디아를 참고 하세요.

                          http://ko.wikipedia.org/wiki/서브버전




                          버전 관리 시스템을 이용해야하는 까닭

                          • 무언가 잘못되었을 때 복구를 돕기 위하여
                          • 프로젝트 진행 중 과거의 어떤 시점으로 돌아갈 수 있게 하기 위하여
                          • 여러사람이 같은 프로젝트에 참여할 경우, 각자가 수정한 부분을 팀원 전체가 동기화하는 과정을 자동화하기 위하여
                          • 소스 코드의 변경 사항을 추적하기 위하여
                          • 소스 코드에서 누가 수정했는지 추적하기 위하여
                          • 대규모 수정 작업을 더욱 안전하게 진행하기 위하여
                          • 가지내기(Branch)로 프로젝트에 영향을 최소화 하면서 새로운 부분을 개발하기 위하여
                          • 접붙이기(Merge)로 검증이 끝난 후 새로이 개발된 부분을 본류(trunk)에 합치기 위하여
                          • 많은 오픈 소스 프로젝트에서 어떠한 형태로든 버전 관리를 사용하고 있으므로
                          • 코드의 특정 부분이 왜 그렇게 쓰여 졌는지 의미를 추적하기 위하여



                          일반적으로 버전 관리 소프트웨어가 사용되는 방식
                          • 갑돌이가 어떤 File을 저장소(repository)에 추가(add) 한다.
                          • 추가되었던 File을 갑돌이가 인출(Check out) 한다.
                          • 갑돌이가 인출된 file을 수정한 다음, 저장소에 예치(Commit) 하면서 설명을 붙인다.
                          • 다음날 을순이가 자신의 작업 공간을 동기화(Update) 한다. 이 때 갑돌이가 추가했던 file이 전달된다.
                          • 을순이가 추가된 file의 수정 기록(Change log)을 보면서 갑돌이가 처음 추가한 file과 이후 변경된 file의 차이를 본다(Diff).


                            SVN 구조
                            대략.. 아래 처럼 된다는 거만 알고 있으면 될듯 합니다.

                           

                           






                          자료출처:http://www.cyworld.com/ruo91/3203221

                          'System' 카테고리의 다른 글

                          [펌]함수 호출규약 [Calling Convention]  (0) 2010.01.01
                          Format String Bug  (0) 2009.12.22
                          Reverse Engineering Cheat-Sheet  (0) 2009.11.30
                          What is SVN[Subversion]?  (0) 2009.11.14
                          어셈블리어 명령어 정리  (3) 2009.11.06
                          플레그는 아무하고나 만나주지 않는다.  (0) 2009.11.03
                          Posted by LinkC

                          2009.11.06 22:33 System

                           

                          명  령  어

                          설                                               명

                          Data Transfer

                          MOV

                          Move

                          데이터 이동 (전송)

                          PUSH

                          Push

                          오퍼랜드의 내용을 스택에 쌓는다

                          POP

                          Pop

                          스택으로부터 값을 뽑아낸다.

                          XCHG

                          Exchange Register/memory with Register

                          첫 번째 오퍼랜드와 두 번째 오퍼랜드 교환

                          IN

                          Input from AL/AX to Fixed port

                          오퍼랜드로 지시된 포트로부터 AX에 데이터 입력

                          OUT

                          Output from AL/AX to Fixed port

                          오퍼랜드가 지시한 포트로 AX의 데이터 출력

                          XLAT

                          Translate byte to AL

                          BX:AL이 지시한 데이블의 내용을 AL로 로드

                          LEA

                          Load Effective Address to Register

                          메모리의 오프셋값을 레지스터로 로드

                          LDS

                          Load Pointer to DS

                          REG←(MEM), DS←(MEM+2)

                          LES

                          Load Pointer ti ES

                          REG←(MEM), ES←(MEM+2)

                          LAHF

                          Load AH with Flags

                          플래그의 내용을 AH의 특정 비트로 로드

                          SAHF

                          Store AH into Flags

                          AH의 특정 비트가 플래그 레지스터로 전송

                          PUSHF

                          Push Flags

                          플래그 레지스터의 내용을 스택에 쌓음

                          POPF

                          Pop Flags

                          스택으로부터 플래그 레지스터로 뽑음

                          Arithmetic

                          ADD

                          Add

                          캐리를 포함하지 않은 덧셈

                          SBB

                          Subtract with Borrow

                          캐리를 포함한 뺄셈

                          DEC

                          Decrement

                          오퍼랜드 내용을 1 감소

                          NEG

                          Change Sign

                          오퍼랜드의 2의 보수, 즉 부호 반전

                          CMP

                          Compare

                          두 개의 오퍼랜드를 비교한다

                          ADC

                          Add with Carry

                          캐리를 포함한 덧셈

                          INC

                          Increment

                          오퍼랜드 내용을 1 증가

                          AAA

                          ASCII adjust for Add

                          덧셈 결과 AL값을 UNPACK 10진수로 보정

                          DAA

                          Decimal adjust for Add

                          덧셈 결과의 AL값을 PACK 10진수로 보정

                          SUB

                          Subtract

                          캐리를 포함하지 않은 뺄셈

                          AAS

                          ASCII adjust for Subtract

                          뺄셈 결과 AL값을 UNPACK 10진수로 보정

                          DAS

                          Decimal adjust for Subtract

                          뺄셈 결과의 AL값을 PACK 10진수로 보정

                          MUL

                          Multiply (Unsigned)

                          AX와 오퍼랜드를 곱셈하여 결과를 AX 또는 DX:AX에 저장

                          IMUL

                          Integer Multiply (Signed)

                          부호화된 곱셈

                          AAM

                          ASCII adjust for Multiply

                          곱셈 결과 AX값을 UNPACK 10진수로 보정

                          DIV

                          Divide (Unsigned)

                          AX 또는 DX:AX 내용을 오퍼랜드로 나눔. 몫은 AL, AX 나머지는 AH, DX로 저장

                          IDIV

                          Integer Divide (Signed)

                          부호화된 나눗셈

                          AAD

                          ASCII adjust for Divide

                          나눗셈 결과 AX값을 UNPACK 10진수로 보정

                          CBW

                          Convert byte to word

                          AL의 바이트 데이터를 부호 비트를 포함하여 AX 워드로 확장

                          CWD

                          Convert word to double word

                          AX의 워드 데이터를 부호를 포함하여 DX:AX의 더블 워드로 변환

                          Logic

                          NOT

                          Invert

                          오퍼랜드의 1의 보수, 즉 비트 반전

                          SHL/SAL

                          Shift logical / arithmetic Left

                          왼쪽으로 오퍼랜드만큼 자리 이동 (최하위 비트는 0)

                          SHR

                          Shift logical Right

                          오른쪽으로 오퍼랜드만큼 자리 이동 (최상위 비트 0)

                          SAR

                          Shift arithmetic Right

                          오른쪽 자리이동, 최상위 비트는 유지

                          ROL

                          Rotate Left

                          왼쪽으로 오퍼랜드만큼 회전 이동

                          ROR

                          Rotate Right

                          오른쪽으로 오퍼랜드만큼 회전 이동

                          RCL

                          Rotate through Carry Left

                          캐리를 포함하여 왼쪽으로 오퍼랜드만큼 회전 이동

                          RCR

                          Rotate through Carry Right

                          캐리를 포함하여 오른쪽으로 오퍼랜드만큼 회전 이동

                          AND

                          And

                          논리 AND

                          TEST

                          And function to Flags, no result

                          첫 번째 오퍼랜드와 두 번째 오퍼랜드를 AND하여 그 결과로 플래그 세트

                          OR

                          Or

                          논리 OR

                          XOR

                          Exclusive Or

                          배타 논리 합 (OR)

                          String Manipulation

                          REP

                          Repeat

                          REP 뒤에 오는 스트링 명령을 CX가 0이 될 때까지 반복

                          MOVS

                          Move String

                          DS:SI가 지시한 메모리 데이터를 ES:DI가지시한 메모리로 전송

                          CMPS

                          Compare String

                          DS:SI와 ES:DI의 내용을 비교하고 결과에 따라 플래그 설정

                          SCAS

                          Scan String

                          AL 또는 AX와 ES:DI가 지시한 메모리 내용 비교하고 결과에 따라 플래그 설정

                          LODS

                          Load String

                          SI 내용을 AL 또는 AX로 로드

                          STOS

                          Store String

                          AL 또는 AX를 ES:DI가 지시하는 메모리에 저장

                          Control Transfer

                          CALL

                          Call

                          프로시저 호출

                          JMP

                          Unconditional Jump

                          무조건 분기

                          RET

                          Return from CALL

                          CALL로 스택에 PUSH된 주소로 복귀

                          JE/JZ

                          Jump on Equal / Zero

                          결과가 0이면 분기

                          JL/JNGE

                          Jump on Less / not Greater or Equal

                          결과가 작으면 분기 (부호화된 수)

                          JB/JNAE

                          Jump on Below / not Above or Equal

                          결과가 작으면 분기 (부호화 안 된 수)

                          JBE/JNA

                          Jump on Below or Equal / not Above

                          결과가 작거나 같으면 분기 (부호화 안 된 수)

                          JP/JPE

                          Jump on Parity / Parity Even

                          패리티 플레그가 1이면 분기

                          JO

                          Jump on Overflow

                          오버플로가 발생하면 분기

                          JS

                          Jump on Sign

                          부호 플레그가 1이면 분기

                          JNE/JNZ

                          Jump on not Equal / not Zero

                          결과가 0이 아니면 분기

                          JNL/JGE

                          Jump on not Less / Greater or Equal

                          결과가 크거나 같으면 분기 (부호화된 수)

                          JNLE/JG

                          Jump on not Less or Equal / Greater

                          결과가 크면 분기 (부호화된 수)

                          JNB/JAE

                          Jump on not Below / Above or Equal

                          결과가 크거나 같으면 분기 (부호화 안 된 수)

                          JNBE/JA

                          Jump on not Below or Equal / Above

                          결과가 크면 분기 (부호화 안 된 수)

                          JNP/JPO

                          Jump on not Parity / Parity odd

                          패리티 플레그가 0이면 분기

                          JNO

                          Jump on not Overflow

                          오버플로우가 아닌 경우 분기

                          JNS

                          Jump on not Sign

                          부호 플레그가 0이면 분기

                          LOOP

                          Loop CX times

                          CX를 1감소하면서 0이 될 때까지 지정된 라벨로 분기

                          LOOPZ/LOOPE

                          Loop while Zero / Equal

                          제로 플레그가 1이고 CX&#8800;0이면 지정된 라벨로 분기

                          LOOPNZ/LOOPNE

                          Loop while not Zero / not Equal

                          제로 플레그가 0이고 CX&#8800;0이면 지정된 라벨로 분기

                          JCXZ

                          Jump on CX Zero

                          CX가 0이면 분기

                          INT

                          Interrupt

                          인터럽트 실행

                          INTO

                          Interrupt on Overflow

                          오버플로우가 발생하면 인터럽트 실행

                          IRET

                          Interrupt Return

                          인터럽트 복귀 (리턴)

                          Processor Control

                          CLC

                          Clear Carry

                          캐리 플레그 클리어

                          CMC

                          Complement Carry

                          캐리 플레그를 반전

                          CLD

                          Clear Direction

                          디렉션 플레그를 클리어

                          CLI

                          Clear Interrupt

                          인터럽트 플레그를 클리어

                          HLT

                          Halt

                          정지

                          LOCK

                          Bus Lock prefix


                          STC

                          Set Carry

                          캐리 플레그 셋

                          NOP

                          No operation


                          STD

                          Set Direction

                          디렉션 플레그 셋

                          STI

                          Set Interrupt

                          인터럽트 인에이블 플레그 셋

                          WAIT

                          Wait

                          프로세서를 일지 정지 상태로 한다

                          ESC

                          Escape to External device

                          이스케이프 명령

                           

                          8086 지시어

                           

                          지시어

                          내                                  용

                          형                                  식

                          SEGMENT
                          -
                          END

                          어셈블리 프로그램은 한 개 이상의 세그먼트들로 구성된다. SEGMENT 지시어는 하나의 세그먼트를 정의한다.

                          segname SEGMENT ; 세그먼트 시작
                          &#8942; ; 세그먼트 내용
                          segname ENDS ; 세그먼트 끝

                          PROC
                          -
                          ENDP

                          매크로 어셈블리에서는 프로그램의 실행 부분을 모듈로 작성할 수 있다. 이 모듈을 프로시저(Procedure)라 부르며, PROC 지시어가 이를 정의한다.

                          procname PROC ; 프로시저의 시작
                          &#8942; ; 프로시저의 내용
                          procname ENDP ; 프로시저의 끝

                          ASSUME

                          어셈블러에게 세그먼트 레지스터와 사용자가 작성한 세그먼트의 이름을 연결시킨다.

                          ASSUME SS:stack_segname,
                          DS:data_segname,
                          CS:code_segname,
                          ES:extra_segname

                          END

                          전제 프로그램의 끝을 나타냄

                          END

                          데이터 정의 지시어 : 프로그램에서 데이터를 저장할 기억 장소를 정의, 초기값 부여

                          DB

                          Define Byte

                          name DB 초기값

                          DW

                          Define Word

                          name DW 초기값

                          DD

                          Define Double Word

                          name DD 초기값

                          DQ

                          Define Quad Word

                          name DQ 초기값

                          DT

                          Define Ten Bytes

                          name DT 초기값

                          EQU

                          변수 이름에 데이터값이나 문자열 정의

                          name EQU 데이터값/문자열

                          =

                          EQU와 달리 정의된 값을 변경 가능


                          EVEN

                          어셈블리시 이 지시어가 사용되는 곳의 주소가 짝수로 되도록 함


                          PAGE

                          어셈블리 리스트의 형식을 결정

                          PAGE [length][,width]

                          TITLE

                          어셈블리 리스트의 각 페이지에 제목 출력

                          TITLE text

                           

                          출처 : Tong - 통토로동통똥똥님의 reverse tech통

                          'System' 카테고리의 다른 글

                          [펌]함수 호출규약 [Calling Convention]  (0) 2010.01.01
                          Format String Bug  (0) 2009.12.22
                          Reverse Engineering Cheat-Sheet  (0) 2009.11.30
                          What is SVN[Subversion]?  (0) 2009.11.14
                          어셈블리어 명령어 정리  (3) 2009.11.06
                          플레그는 아무하고나 만나주지 않는다.  (0) 2009.11.03
                          Posted by LinkC

                          2009.11.03 23:59 System


                          우리가 cpu에서 플레그 레지스터라는 이야기를 많이 들어보셨으리라 생각합니다. 일단 어셈블리를 공부하시기로 한 이상 플레그 레지스터를 모르고 넘어간다는 일은 수동기어를 장착한 차량에서 기어바꿀줄 모르고 1단으로만 기어를 놓고 달릴줄만 아는 상황과 비슷하다고 말씀 드릴 수 있습니다. (좀 표현이 이상했나요? ^^a)

                          플레그레지스터는 CPU내부의 명령에 따른 결과나 명령수행방식을 설정하거나 설정되는 레지스터를 말합니다.

                          이 레지스터는 다음과 같은 항목으로 구성되어 있습니다. 


                          CF - carry flag(케리플레그) 바로 전 연산에서 자리를 넘치거나 쉬프트등으로

                                  밖으로 밀려난 비트값이 1일경우 1로 설정되는 플레그 

                          PF - Parity flag(패리티 플레그) 바로전에 연산된 값의 결과에 1인 비트수가 짝수일경우 1로 설정됨. 

                          AF - Adjust flag(보정 플레그) BCD 연산을 위하여 보정에 사용되는 플레그 

                          ZF - Zero flag(제로 플레그) 바로 위의 연산결과값이 0이 나오거나 비교시 두 값이 같으면 1로 설정 

                          SF - Sign flag(사인 플레그) 연산결과의 부호를 나타내며 결과값이 양수일때는 0으로 음수일때는 1로 설정 

                          OF - Overflow flag(오버플로우 플레그) 연산결과가 양의 정수값이나 음의 정수값 범위를 넘칠경우 설정되는 플레그, 케리플레그와 동작이 유사하여 케리플레그와 값이 일치하는 경우도 종종 있다.

                          이외에도 시스탬종작을 위한 IF , NT , RF , VM , IOPL 등의 플레그가 있지만 오늘 강좌하려는 범위에서

                          넘어가므로 생략하기로 합니다. 


                           그럼 이 플레그들과 명령들과의 관계를 알아보기로 합니다. 이제부터 필요한 준비물이 있습니다. 어셈블리

                          책 중 CPU명령어가 자세히 나온 책을 하나 선정하여 영향받는 플레그와 영향주는 플레그항목까지 기록된

                          자료를 준비해 주시기 바랍니다. 어차피 어셈블리 프로그래밍을 한다면 이정도의 준비물은 있어야 합니다. 


                           우리가 플레그하면 조건분기명령과 많이 연관을 짓습니다. 만약 ax 레지스터 값이 5인지를 알려면 다음과

                          같이 합니다. 


                          cmp ax , 5 
                          je xxx ;     ax값이 5일경우 점프할곳 
                          jne yyy ;   ax값이 5가 아닐경우 점프할곳 

                          이정도 부분까지는 대충 이혜하실수 있어야 다음 부분을 보셔도 이혜가 가시게 됩니다.

                          위의 명령의 경우 다음과 같이 바꿀수 있습니다.

                          sub ax , 5 

                          je xxx ;      ax값이 5일경우 점프할곳 
                          jne yyy ;    ax값이 5가 아닐경우 점프할곳 

                          대부분 어셈블리 명령을 여타언어에서의 "if"명령과 많이 연관시켜 생각하기 때문에 "if"와 매우 유사한

                          기능을 하는 cmp명령이 비교명령으로 생각하여 cmp 명령으로 비교연산을 하는 경우가 생깁니다.

                          하지만 이는 어셈블리 명령으로 다른 언어를 흉내 내려할때에 사용하는것이지 어셈블리를 무엇때문에

                          사용하려 하는지에 대하여 고찰해 보아야 할 필요가 있음을 느끼게 하는 대목입니다. 

                          일단은 먼저 명령과 플레그에 관하여 상관관계를 알아봐야 합니다. 우리거 명령표를 볼때 (좀 자세히 나온것)

                          영향받는 플레그와 영향주는 플레그가 표기되어 있을것입니다.

                          예를 들어서,

                          dec 명령의 경우 명령이 실행에 영향받는 플레그 - 없음

                          명령이 실행후에 영향주는 플레그                      - OF, SF, ZF, AF, PF 


                          이 뜻은 dec 명령은 실행시 실행특성에 영향을 주는 플레그는 존재 안하며 실행후 결과연산특성이

                          적용되는 플레그들은 OF, SF, ZF, AF, PF 가 있다는 뜻입니다. 즉 dec 명령 수행후 결과값이 음수

                          일경우 SF 가 1로 설정이 되고 (음수이므로) ZF는 0이 되며(0이 아니므로) PF는 결과값의 내부

                          패리티를 채크하여 1이 짝수개이면 1이 설정되고 홀수개면 0이 설정되게 되어 있다는 뜻입니다.

                          그러므로 dec 연산을 한후 사용할수 있는 조건분기명령은

                          dec ax 

                          jz xxxx ;    결과가 0이면 점프 
                          js xxxx ;    결과가 음수일경우 
                          jp xxx ;      결과가 짝수 패리티일경우 

                          등이 될수 있습니다. 따라서 이러한 사실들로 우리는 cmp 명령이 결과값에 영향을 안주고

                          플레그에만 영향을 주는 sub명령임을 알 수 있습니다. 여기서 원래라면 플레그와 음수/양수와

                          부호없는 수의 크기비교에 따른 플레그값의 설정을 설명해야 하지만 지면의 크기와 여러분의

                          공부를 위하여 여러분께 숙제로 남겨드리기로 하겠습니다. 

                          (헉.. 돌이 날라오는군요) 

                          그럼 다음으로 플레그의 용법이 조건분기에만 한하지 않음을 예로 들어보이겠습니다.

                          이 예중 대표적인 예가 adc 명령입니다.  우리가 64비트수치에다가 어떤 수를 더한다고

                          생각합니다. 하지만 우리가 쓰는 cpu는 32비트 이므로 64비트 수치를 바로 계산할수

                          있는 명령은 없습니다. 따라서 먼저 64비트중 하위 32비트를 덧셈을 한 후 더한값이

                          자리를 넘칠 경우 상위 32비트를 더할때 1을 더 더해주면 됩니다. 바로 이럴때 사용되는

                          것이 carry flag 입니다. 위에서 설명했듯이 케리플레그는 연산의 자리를 넘치거나 했을때

                          설정되는 플레그입니다. add 명령은 결과값에 대하여 carry 플레그에 영향을 주는 명령입니다.

                          따라서 x 라는 64비트 변수를 y라는 64비트 변수로 더한다고 할때 그 연산루틴은 다음과 같이

                          설정할수 있습니다. 


                          mov eax , dword ptr y[0] ;  먼저 y의 하위 32비트 값을 얻어서 
                          add dword ptr x[0] , eax ;   x의 하위 32비트에 더한다음 
                          mov eax , dword ptr y[4] ;  다음 y의 상위 32비특밧을 얻어서 
                          adc dword ptr x[4] , eax ;   이전하위 32비트의 더한 넘친자리 수 까지 더하여 x의 상위 32비트에 더한다 

                          여기서 질문 2가지를 하실수 있게 되실겁니다. 
                          Q1) adc 는 어떤 일을 하는데 하위에서 자리넘침이 있는지를 알수 있나요? 

                          A1) 옙, 그건 먼저 add로 연산했을 경우 add 명령은 CF (carry flag)에 결과값 영향을 끼칩니다.

                          carry는 연산결과가 변수타입이 표시할 수 있는 범위를 넘쳤을 경우 1로 설정되므로 두 덧셈의

                          결과가 dword (더블워드,32비트)를 넘쳤을 경우 1로 설정됩니다. 후에 밑에 쓰인 adc 명령은

                          덧셈을 하면서 CF값까지 같이 더하는 명령입니다. 즉, 바로 위쪽의 add 명령으로 인하여

                          자리넘침이 생겼을 경우 케리플레그값이 1이 되므로 상위 32비트를 더하면서 밑에 32비트 덧셈

                          결과의 자리넘침 결과(=CF)값가지 더해지게 되는 것이지요. 이해를 위하여 다음 예제를 넣겠습니다. 


                          ex1) 
                          mov eax , 0 ;eax 를 0으로 만듬 
                          clc ;케리플레그(CF) 를 0으로 만듬,또는 클리어한다라고 
                          adc eax , 0 ;표현, 그런후 adc 명령으로 eax + 0 + CF를 연산 
                          ------------- 
                          결과 eax = 0 

                          ex2) 
                          mov eax , 0 ;        eax 를 0으로 만듬 
                          stc ;                    케리플레그(CF) 를 1로 만듬,또는 설정한다라고 
                          adc eax , 0 ;        표현, 그런후 adc 명령으로 eax + 0 + CF를 연산 
                          ------------- 
                          결과 eax = 1 

                          이제 adc 명령이 이혜가 가시는지요 ^^; 

                          Q2) 위의 소스를 보면 하위 32비트 덧셈 명령인 add 명령과 케리플레그 의 형향을 받는

                          덧셈인 adc 명령사이에 mov 라는 명령이 쓰였습니다. 그렇다면 이 mov 명령의 영향에

                          의해서 CF값이 바뀌어 adc 명령의 수행에 이상을 주지 않을까요? 

                          A2) 위의 설명을 좀더 이혜할 수 있는 기회입니다. 이 설명의 제일 앞 중에 영향을 주는

                          플레그리스트가 각 명령별로 틀리다고 말씀 드렸을 것입니다. 다행히도 mov 명령은

                          CF 플레그에 영향을 받지도 주지도 않는 명령어 입니다. 따라서 mov 명령은 CF 값을

                          변화시키거나 하지 않습니다. 참고로 mov 명령은 영향받는 플레그도 없고 주는 플레그도 없는

                          명령입니다. 그러므로 add 와 adc 사이에는 CF에 영향을 주지 않는 명령이라면 얼마든지

                          써도 되는 것입니다. ^^ 


                          이번에는 어셈블리를 이용한 최적화된 조건분기를 보여드리겠습니다.

                          만약 x값이 y값보다 큰지, 같은지 , 작은지를 비교해야 할 경우가 생긴다고 합니다.

                          이럴경우 일반적으로 연산을 구현할때

                          if (x=y) 


                                  file://같을때 처리문 

                          else 

                                  if (x<y) 
                                 { 
                                            file://x가 y보다 작을때 처리문 
                                  } 
                                  else 
                                 { 
                                            file://x가 y보다 클때 처리문 
                                  } 

                          과 같은 비교조건문이 생기게 됩니다. 이를 컴파일하여 디스어셈블 할 경우

                          엄청나게 최적화되지 않은 컴파일러라면 다음과 같이 됩니다.

                          file://VC 6.0 디스어셈블 예

                          102: if (x=y) 

                          00402F31 mov eax,dword ptr [ebp-54h] 
                          00402F34 mov dword ptr [ebp-50h],eax 
                          00402F37 cmp dword ptr [ebp-50h],0 
                          00402F3B  je   CTestasmView::OnBtnAsmTest+46h (00402f46) 
                          103: { 
                          105: } 
                          106: else 
                          00402F44 jmp  CTestasmView::OnBtnAsmTest+5Eh (00402f5e) 
                          107: { 
                          108: if(x<y) 
                          00402F46 mov ecx,dword ptr [ebp-50h] 
                          00402F49 cmp ecx,dword ptr [ebp-54h] 
                          00402F4C jge CTestasmView::OnBtnAsmTest+57h (00402f57) 
                          109: { 
                          111: } 
                          112: else 
                          00402F55 jmp CTestasmView::OnBtnAsmTest+5Eh (00402f5e) 
                          113: { 
                          115: } 
                          116: } 

                          하지만 이를 어셈블리 코드로 고친다음 다음과 같이 할 수 있습니다. 

                          mov eax , y 

                          cmp x , eax 
                          jg Lvl1 ;      x가 y보다 클경우 처리 
                          jl Lvl2 ;       x가 y보다 작을경우 처리 
                          ;                x와 y가 같을경우 처리 
                          ... 
                          jmp CmpEnd 

                          Lvl1: 
                          ... ;             x가 y보다 클경우 처리문 
                          jmp CmpEnd 

                          Lvl2: 
                          ... ;             x가 y보다 작을경우 처리문 

                          CmpEnd: 


                          좀더 사용 명령수가 줄어들게 됩니다. 뿐만 아니라 명령처리에 대한 흐름을 원활하기

                          위하여 이런 분기가 일어나지 않도록 컨디션 mov 명령이 팬티엄pro부터 생겨났으므로

                          조건에 따라 처리해야할 변수의 갯수가 적을 경우 이런 명령을 이용하면 무분기 조건처리도

                          가능합니다. 물론 flag와 명령의 처리특성을 이용하신다면 무분기 조건처리에 대한 여러가지

                          편법 또한 이용하실수 있게 되실겁니다. 


                          이번 강좌또한 마치며 한말씀 드리려 합니다. 항상 기본을 하며 말씀을 드리는 것이지만

                          어셈블리를 사용하실때 왜 프로그램의 소스에 어셈블리를 사용하는가와 어떨때 어셈블리를

                          사용하고 어떨때 사용하지 않는것이 낳은지를 잘 아시는것이 좋은 프로그래머의 예라 할 수

                          있습니다. 아직까지도 이런 부분에서 많은 분들이 어셈블리에 대하여 많은 소음이 끊이지

                          않고 있습니다. 저는 따로 생각하지 않고 적어도 어셈블리는 상용프로그램에서도 많이 사용되고

                          있으며 무언가 필요하기 때문에 외국 고수준 프로그래머들도 사용하고 있으며 같은 로직으로

                          되었을때 타사제품과 좀더 경쟁력을 갖추기 위하여 나은 수행속도를 원할때 선택되는 사항이라는

                          점을 알아주시면 좋겠습니다. 

                          출처 - http://ttongfly.net/zbxe/?document_srl=45194

                          'System' 카테고리의 다른 글

                          [펌]함수 호출규약 [Calling Convention]  (0) 2010.01.01
                          Format String Bug  (0) 2009.12.22
                          Reverse Engineering Cheat-Sheet  (0) 2009.11.30
                          What is SVN[Subversion]?  (0) 2009.11.14
                          어셈블리어 명령어 정리  (3) 2009.11.06
                          플레그는 아무하고나 만나주지 않는다.  (0) 2009.11.03
                          Posted by LinkC
                          이전버튼 1 2 3 이전버튼

                          블로그 이미지
                          LinkC

                          태그목록

                          Tistory Cumulus Flash tag cloud by BLUEnLIVE requires Flash Player 9 or better.

                          공지사항

                          Yesterday31
                          Today2
                          Total331,153

                          달력

                           « |  » 2019.8
                                  1 2 3
                          4 5 6 7 8 9 10
                          11 12 13 14 15 16 17
                          18 19 20 21 22 23 24
                          25 26 27 28 29 30 31

                          최근에 받은 트랙백

                          글 보관함


                          . .