2014년 10월 27일 월요일

역 어셈블(disassemble)을 시도해본다


예전에 공부했던 자료들 중에서 어셈블과 소스코드의 주소와 어셈블 명령을

참조해야 되는 자료가 있는데 자료를 본지 너무 오래 되서 기억도 잘 안나고

그때는 어떻게 했는지 기억도 안나고 그래서 좀 찾다가 보니까 괜찮아 보이는 자료를

찾아서 정리 좀 하려고 합니다.


역 어셈블을 하기 위해서 사용되는 방법은 바로 'objdump' 유틸리티 입니다.


Ubuntu 에서는 objdump는 기본으로 사용할 수 있게 되어 있습니다.

그리고 옵션이 생각보다는 꽤 있죠. 자세하게 알아보시려면 objdump 옵션을 검색해서

찾아 보시면 됩니다. 우리가 사용하는 역 어셈블은 -d 옵션을 사용합니다.

-D 옵션도 역 어셈블을 하는데 전체를 다하기 때문에 소스코드가 긴 경우에는

너무 많이 출력되기 때문에 알아보기 힘들수가 있습니다. 그래서 -d 옵션을 사용하는 것을

추천 드립니다. 그럼 어떻게 사용하는 보겠습니다.


소스 코드는 되게 간단한 Hello World 프로그램을 사용하겠습니다. 자 그럼 이제

소스 코드를 컴파일하고 역 어셈블을 시도해보겠습니다.


컴파일을 할 때는 gcc를 사용합니다. 그리고 두 개의 옵션을 주었습니다.

    -c : 링크 파일만 생성 [파일명.o]

    -g : 디버그 옵션

두 개의 옵션만 주면 역 어셈블을 수행할 수 있습니다.

자 그럼 objdump로 수행해보겠습니다.


    objdump -d [링크파일명]

이렇게 입력을 하면 역 어셈블 내용이 화면에 출력 됩니다.

왼쪽에 있는 부분은 주소와 관련된 부분이고 오른쪽 부분은 어셈블 내용입니다.

그런데 이렇게만 보면 이해하기 어려우니까 옵션을 하나 더 줘보겠습니다.


위와 동일하지만 -S 옵션을 하나 더 주었습니다. (S는 대문자입니다.)

        objdump -d -S [링크파일명]

이렇게 하면 어셈블이 나오면서 해당 코드도 같이 표시 되기 때문에

이해하기가 약간은 쉬워집니다. 하지만 저는 여기서 문제가 하나 발생했습니다.

그건 바로! 제가 하는 것은 인텔 계열 프로그램을 역 어셈블 하는 것이 아니고

ARM 계열 소스코드를 역 어셈블 해야 된다는 것이죠.

그래서 저는 방법을 찾으려고 했습니다. 하지만 쉬운 문제는 아니었죠.

하지만 구글신은 여러 가지 방법을 알려주더라고요. 그래서 저는 방법을 찾았습니다.

우선 이것을 하기 위해서는 무언가를 하나 설치해야 됩니다.

$ wget http://www.cl.cam.ac.uk/freshers/raspberrypi/tutorials/os/downloads/arm-none-eabi.tar.bz2
--2012-08-16 18:26:29--  http://www.cl.cam.ac.uk/freshers/raspberrypi/tutorials/os/downloads/arm-none-eabi.tar.bz2
Resolving www.cl.cam.ac.uk (www.cl.cam.ac.uk)... 128.232.0.20, 2001:630:212:267::80:14
Connecting to www.cl.cam.ac.uk (www.cl.cam.ac.uk)|128.232.0.20|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 32108070 (31M) [application/x-bzip2]
Saving to: `arm-none-eabi.tar.bz2'

100%[======================================>] 32,108,070   668K/s   in 67s

2012-08-16 18:27:39 (467 KB/s) - `arm-none-eabi.tar.bz2' saved [32108070/32108070]

$ tar xjvf arm-none-eabi.tar.bz2
arm-2008q3/arm-none-eabi/
arm-2008q3/arm-none-eabi/lib/
arm-2008q3/arm-none-eabi/lib/libsupc++.a
arm-2008q3/arm-none-eabi/lib/libcs3arm.a
...
arm-2008q3/share/doc/arm-arm-none-eabi/info/gprof.info
arm-2008q3/share/doc/arm-arm-none-eabi/info/cppinternals.info
arm-2008q3/share/doc/arm-arm-none-eabi/LICENSE.txt

위와 같이 입력을 해줍니다.

그럼 arm-non-eabi tool chain을 설치하는 것인데요.

raspberry pi 의 tool chain 이니까 없어지지는 않겠죠. 압축을 풀고나서 'arm-2008q3/arm-none-eabi/bin'

위치로 들어가보면 'objdump'가 있을 겁니다.


그럼 PATH 설정하는건 귀찮으니까 적당히 복사해서 사용해 보죠.

적당한 위치에 복사한 objdump에 같은 옵션을 주고 모듈 프로그램의 링크 파일을 역 어셈블 합니다.


그럼 이제 위와 같이 ARM으로 컴파일된 모듈도 역어셈블을 할 수가 있게됩니다.

참 쉽죠잉?

궁금한게 더 있으시다면 덧글이나 메일로 문의를 주세요.

아는대로 답변을 해드리겠습니다. 그럼 오늘은 끝~!

2014년 4월 17일 목요일

안드로이드 NDK 설치(Windows OS) [3]


어제에 이어서 마무리를 향해 달려가 보도록 합시다.

어제까지 환경설정을 위한 SDK sygwin, NDK 설치 & 설정 하였습니다.

오늘은 마무리로 Java에서 .c 파일을 가지고 오는 것과 빌드와 실행을 해보겠습니다.

안드로이드 프로젝트 아래에 있는 src 폴더에 MainActivity.java 코드를 수정해서

jni
폴더에 있는 ndktest.c 파일을 읽을 있도록 해보겠습니다.

------------------------MainActivity.java-----------------------------
package sample.ndktest;

import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.view.Menu;

public class MainActivity extends Activity {

 //
라이브러리 로드 - Android.mk 이름과 매치
 static {
  System.loadLibrary("ndktest");
 }

 //
코드의 함수를 선언 - 반드시 ndktest.c 일치
 private native String invokeNativeFunction();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
     
        //
코드를 호출
        String hello = invokeNativeFunction();
        new AlertDialog.Builder(this).setMessage(hello).show();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
 
}
----------------------------------------------------------------------

MainActivity.java
에서 새로 추가한 부분은 진하게 표시 했으니 보기 쉽겠죠.

이제 ndktest.c 파일을 빌드하러 가보겠습니다.

이제 cygwin 터미널을 사용해서 파일 빌드를 해보죠.

파일을 빌드하기 위해서 중요한 것이 있습니다.

    1.
안드로이드 프로젝트의 위치

    2.  ndk-build
파일의 위치

가지 인데. 안드로이드 프로젝트의 위치는 SDK 이클립스가 처음 실행될

설정하도록 되어 있습니다. 만약 어디로 했는지 모르겠다면

생성한 프로젝트에서 마우스 오른쪽 버튼을 눌러서 'propertise' 누르게 되면 창이 뜨는데

그곳에 화살표로 가르키는 부분이 안드로이드 프로젝트의 위치 입니다.

ndk-build
파일의 위치는 안드로이드 ndk 압축파일 해제한 위치입니다.

--------------------------------- 실행 내용 -------------------------------------
cube@cube-PC /cygdrive/c/IDE/adt-bundle-windows-x86-20131030/workspace/ndktest
$ /cygdrive/c/IDE/android-ndk-r9c/ndk-build
Android NDK: WARNING: APP_PLATFORM android-19 is larger than android:minSdkVersion 8 in ./AndroidManifest.xml
[armeabi] Cygwin         : Generating dependency file converter script
[armeabi] Compile thumb  : ndktest <= ndktest.c
[armeabi] SharedLibrary  : libndktest.so
[armeabi] Install        : libndktest.so => libs/armeabi/libndktest.so
--------------------------------------------------------------------------------

제대로 실행이 됐다면 이클립스에 파일이 생성이 되었을 것입니다.

보인다면 F5 눌러서 프로젝트 리소스를 새로고침 해보시고 안되면 다시 파일의 이름과

다른 것들을 확인해 보시기 바랍니다.

이제 파일이 제대로 생성된 분들은 프로젝트를 실행시켜서 제대로 동작하는지 확인해 봅시다.

실행방법은 특별한 것이 없습니다만. 안드로이드 프로젝트에서 마우스 오른쪽 버튼 눌러서

Run As
있는 Android Application 선택해 줍니다.
(
스크린샷이 안되서 부득이하게 글로 대체 합니다.)

생성했던 안드로이드 프로젝트 이름과 같은 어플이 생긴 것을 확인했습니다.

어플을 실행시켜 줍니다.

실행하면 화면에 글이 나오는 것을 확인할 있습니다.

화면에 나오는 글은 jni 폴더에 있는 ndktest.c 코드에 있는 글이 출력되는 것입니다.

자세히 어떤 부분이신지 궁금하시다면 스스로 찾아 보시기 바랍니다.

어렵지 않습니다. 여기까지 진행하셨다면 수정은 쉬울테니까 저는 이만 하도록 하겠습니다.

이건 NDK 설치에 대한 문서이기 때문에 자세한 것은 나중에 공부해야 겠네요.

그럼 저는 내일 다른 내용을 가지고 있겠네요. 그럼 수고하셨습니다.