Friday, February 10, 2012
Retabbed
Login | Register
아티클
  Search
닷넷 프로그램 만들기
닷넷 프로그램 만들기

닷넷 프로그램을 컴파일 하면 중간언어로 된 실행파일을 만든다. 중간언어는 특정한 프로세스에 맞춘 어셈블리가 아니라 그 전단계로 어떤 기계어로던 번역에 편리한 언어로 만들어진 어셈블리로 생각하면 된다. 백마디 말보다 직접 만들어서 살펴보자. 우선 비주얼스튜디오닷넷을 실행한다.(VS.NET 2003 기준) VS.NET을 실행하고 파일->새로만들기->프로젝트 메뉴을 선택한다. 그러면 다양한 프로젝트의 종류가 나오는데 가장 간단히 만들어 보기 위하여 좌측의 프로젝트 형식은 Visual C# Project, 템플릿은 콘솔응용프로그램을 선택하고 프로젝트 디렉토리를 적절한 곳으로 입력한 후에(기본은 내문서\Visual Studio Projects 아래에 만들어진다.) 확인을 누른다.

그러면 기본 Class1.cs파일의 내용이 아래와 같이 나온다.

using System;

 

namespace ConsoleApplication2

{

        ///

        /// Class1 에 대한 요약 설명입니다.

        ///

        class Class1

        {

               ///

               /// 해당 응용 프로그램의 주 진입점입니다.

               ///

               [STAThread]

               static void Main( string [] args)

               {

                       //

                       // TODO: 여기에 응용 프로그램을 시작하는 코드를 추가합니다.

                       //

               }

        }

}

 

 


여기에 아래와 같이 코드를 입력 한다.

using System;

 

namespace ConsoleApplication2

{

        ///

        /// Class1에 대한 요약 설명입니다.

        ///

        class Class1

        {

               ///

               ///해당 응용 프로그램의 주 진입점입니다.

               ///

               [STAThread]

               staticvoidMain(string[] args)

               {

                       //

                       // TODO: 여기에 응용 프로그램을 시작하는 코드를 추가합니다.

                       //

                       int num = int.Parse(args[0]);

  

                       int sum = 0;

                       for(int i=1; i<=num; i++)

                              sum += i;

                       Console.WriteLine("합계 = {0}", sum);

 

                       Console.Read();

               }

        }

}

 

 


이 프로그램은 커맨드라인(명령줄) 파라메터로 입력된 숫자까지 1부터 합을 구하는 프로그램이다. 메뉴에서 빌드->솔루션빌드를 선택하여 프로그램을 컴파일 한다. 그러면 프로젝트 디렉토리에 .exe파일이 생성된다. 디컴파일러는 VS.NET으로 할수가 없고 인터넷에서 적당한 툴을 다운 받는다. 여기서는 "Reflector for .NET "을 사용한다. 이 프로그램은 http://www.aisto.com/roeder/dotnet/에서 받을 수 있다. 이 프로그램을 사용하면 아래와 같은 중간언어 결과를 얻을 수 있다.(이 프로그램의 상세한 사용법은 차후에 다시한번 설명하기로 한다)

.namespace ConsoleApplication2
{
    .class private auto ansi beforefieldinit Class1
        extends object
    {
        .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
        {
            // Code Size: 7 byte(s)
            .maxstack 1
            L_0000: ldarg.0
            L_0001: call instance void object::.ctor()
            L_0006: ret
        }

        .method private hidebysig static void Main(string[] args) cil managed
        {
            .custom instance void [mscorlib]System.STAThreadAttribute::.ctor()
            .entrypoint
            // Code Size: 50 byte(s)
            .maxstack 2
            .locals init (
                int32 num1,
                int32 num2,
                int32 num3)
            L_0000: ldarg.0
            L_0001: ldc.i4.0
            L_0002: ldelem.ref
            L_0003: call int32 int32::Parse(string)
            L_0008: stloc.0
            L_0009: ldc.i4.0
            L_000a: stloc.1
            L_000b: ldc.i4.1
            L_000c: stloc.2
            L_000d: br.s L_0017
            L_000f: ldloc.1
            L_0010: ldloc.2
            L_0011: add
            L_0012: stloc.1
            L_0013: ldloc.2
            L_0014: ldc.i4.1
            L_0015: add
            L_0016: stloc.2
            L_0017: ldloc.2
            L_0018: ldloc.0
            L_0019: ble.s L_000f
            L_001b: ldstr "\ud569\uacc4 = {0}"
            L_0020: ldloc.1
            L_0021: box int32
            L_0026: call void [mscorlib]System.Console::WriteLine(string, object)
            L_002b: call int32 [mscorlib]System.Console::Read()
            L_0030: pop
            L_0031: ret
        }

    }
}

이 코드는 이해할려고 할 필요가 없다. 단지 이런식으로 생긴 어셈블리로 만들어진다는 정도만 알아 두면 된다. Reflector for NET은 다양한 언어로 디컴파일 하는 기능도 가지고 있다. 아래는 비주얼베이직.NET으로 디컴파일 한 결과다.

 

Imports System

 

Namespace ConsoleApplication2

    FriendClass Class1

        ' Methods

        PublicSubNew()

        EndSub

 

        _

        PrivateSharedSub Main(ByVal args AsString())

            Dim num1 AsInteger = Integer.Parse(args(0))

            Dim num2 AsInteger = 0

            Dim num3 AsInteger = 1

            DoWhile (num3 <= num1)

                num2 = (num2 + num3)

                num3 += 1

            Loop

            Console.WriteLine(ChrW(54633) & ChrW(44228) & " = {0}", num2)

            Console.Read

        EndSub

 

    EndClass

EndNamespace

 

 

 

변수의 이름만 나오지 않을 뿐 프로그램은 원래의 모양대로 그대로 다시 만들 수 있음을 알수 있다. 또한 비주얼베이직과 C#완전하게 서로 호환가능한 언어구조를 가지고 있다는 사실 또한 알수 있다. 닷넷은 중간 언어를 매개로 실제 개발에 사용되는 언어와는 완전히 무관하게 설계가 되어 있는 것이다. 이래한 툴들 때문에 닷넷으로 만든 프로그램은 소스보호차원에서 보면 바이너리로 만드는 것보다는 훨씬 약하다는 것을 알 수 있다. 소스 보호를 위해서 특별한 조치가 필요한 중요한 소프트웨어라면 소스를 읽기 힘들게 하는 암호화 프로그램을 사용하는 것이 바람직하다 하겠다.

 


게시일자 Tuesday, October 04, 2005 (Archive on Tuesday, October 11, 2005)
게시자: 사이트관리자  저자: 불나방
돌아가기

평점:
평가:
평가 올리기

현재평점평균: 1.00
평점: 1
Terms | Privacy | host
Copyright 2005 Code99.NET
 | 아티클 | 자료실 | 블로그 | Q&A | 관리자에게