'2018/06'에 해당되는 글 4건

  1. 2018.06.06 pintool
  2. 2018.06.06 Intel PIN (2)
  3. 2018.06.02 IDAPython Plugin
  4. 2018.06.02 [DEFCON 2018 CTF] ELF Crumble

pintool

reversing 2018. 6. 6. 17:26

이번 포스팅에서는 pintool 사용법 및 예제코드에 대한 간단한 분석을 진행한다.

 

pintool 이란, Intel PIN SDK 를 이용해 개발한 라이브러리이다. PIN 이란 프로그램의 플러그인(?) 이라 생각하면 될 것 같다.

혹여나 설치를 하지 못했다면, http://woosunbi.tistory.com/170 을 참고하기 바란다.

 

기본적인 사용 방법은,

# ./pin -t [ .so 파일] -- [분석하고자 하는 파일]

 

# Instrumentation Granularity

: Pin 의 Instrumentation Granularity 에 따라 4가지 방식으로 Binary Instrumentation(Just in time) 이 가능하다.

 

1. Trace Instrumentation (TRACE_AddInstrumenFunction API 호출)

: Trace 단위로 Instrument 하는 모드이다. Trace 는 일반적으로 Branch 의 Target 에서 시작하여 Call, Return 을 포함하여 무조건 분기에서 끝이 난다.

 

2. Instruction Instrumentation (INS_AddInstrumentFunction API 호출)

: 하나의 Instruction 단위로 Instrument 하는 모드이다.  즉, 모든 명령어 실행 시 호출하는 함수이다.

 

3. Image Instrumentation (IMG_AddInstrumentFunction API 호출)

: 실행 바이너리 또는 공용 라이브러리가 주소 공간에 올라올 때 Instrument 하는 모드이다.

IMG Loading, Unloading 등 이 때 실행되는 함수이다.

 

4. Routine Instrumentation(RTN_AddInstrumentFunction API 호출)

: 특정 함수를 실행함수의 전후로 Instrument 하는 모드이다. 모든 함수 실행과 관련해 호출하는 함수이다.

 

본인이 하고자하는 목적에 맞게 granularity 를 사용해야 한다.!  자칫 심각한 오버헤드를 초래할 수 있다..

 

 

# 예제코드 분석

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <fstream>
#include "pin.H"
 
ofstream OutFile;
 
// The running count of instructions is kept here
// make it static to help the compiler optimize docount
static UINT64 icount = 0;
 
// This function is called before every instruction is executed
VOID docount() { icount++; }
 
// Pin calls this function every time a new instruction is encountered
VOID Instruction(INS ins, VOID *v)
{
    // Insert a call to docount before every instruction, no arguments are passed
    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_END);
}
 
KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool",
    "o""inscount.out""specify output file name");
 
// This function is called when the application exits
VOID Fini(INT32 code, VOID *v)
{
    // Write to a file since cout and cerr maybe closed by the application
    OutFile.setf(ios::showbase);
    OutFile << "Count " << icount << endl;
    OutFile.close();
}
 
/* ===================================================================== */
/* Print Help Message                                                    */
/* ===================================================================== */
 
INT32 Usage()
{
    cerr << "This tool counts the number of dynamic instructions executed" << endl;
    cerr << endl << KNOB_BASE::StringKnobSummary() << endl;
    return -1;
}
 
/* ===================================================================== */
/* Main                                                                  */
/* ===================================================================== */
/*   argc, argv are the entire command line: pin -t <toolname> -- ...    */
/* ===================================================================== */
 
int main(int argc, char * argv[])
{
    // Initialize pin
    if (PIN_Init(argc, argv)) return Usage();
 
    OutFile.open(KnobOutputFile.Value().c_str());
 
    // Register Instruction to be called to instrument instructions
    INS_AddInstrumentFunction(Instruction, 0);
 
    // Register Fini to be called when the application exits
    PIN_AddFiniFunction(Fini, 0);
 
    // Start the program, never returns
    PIN_StartProgram();
 
    return 0;
}
 
 
cs

위의 샘플코드는 프로그램 시작부터 종료까지 수행된 명령어의 갯수를 출력한다.

 

먼저, 결과 값을 담아낼 파일을 오픈하고 있다.

그 후 INS_AddInstrumentFunction() 함수를 통해 각각의 Instrcution 마다 콜백함수를 지정한다.

 

1
2
3
4
5
VOID Instruction(INS ins, VOID *v)
{
    // Insert a call to docount before every instruction, no arguments are passed
    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_END);
}
cs

콜백함수인 Instruction 함수를 살펴보면,

INS_InsertCall() 함수를 호출하는데, IPOINT_BEFORE 인자를 통해 각 Instruction 앞에 docount() 함수를 호출할 것임을 알린다.

결과적으로, 위 함수를 통해 각 Instruction 마다 docount() 호출하고 명령어의 갯수를 icount 변수에 저장한다.

 

마지막으로, PIN_AddFiniFunction() 함수를 사용하여 프로그램이 종료될 때 호출할 함수(Fini)를 지정해준다.

예제코드에서의 Fini() 함수는 오픈한 파일에 결과 값을 담는 역할을 한다.

 

이로써 pintool 의 가장 기본적인(?) 부분에 대해서  간단히 소개한거같다..

이후에는 본인이 원하는 업무나 공부에 활용하기 위한 pintool 을 만들어보는게 좋을 것 같다.. 

'reversing' 카테고리의 다른 글

pintool  (0) 2018.06.06
code injection  (0) 2018.01.09
angr  (0) 2017.02.18
gdb child process debugging  (1) 2016.11.04
IDA remote gdb debugging with gdbserver  (0) 2016.04.10
예외 처리를 이용한 Anti-Debugging  (0) 2016.03.12
Posted by woodonggyu

댓글을 달아 주세요

Intel PIN

utility 2018. 6. 6. 17:12

PIN 이란, Intel 에서 제작한 DBI(Dynamic Binary Instrumentation Framework) 이다. 

DBI 를 이용하면 실행 중인 프로세스에 임의의 코드를 삽입하는 것이 가능하다.

 

영어로 작성되어있지만, 메뉴얼도 잘 작성이 되어있고 예제코드 또한 꽤나 있기에 쉽게 이해할 수 있다.

 

# Install

다운로드 : https://software.intel.com/en-us/articles/pin-a-binary-instrumentation-tool-downloads

다양한 환경에서 지원하고 있으며, 쉽게 설치 및 사용 가능하다.

 

해당 포스팅에서는 Linux 에서의 사용방법을 간단히 소개한다.

OS : Ubuntu 16.04 64bit

 

# tar -xvzf pin~.tar.gz

# cd pin~.tar.gz/source/tools/ManualExamples

# make all            // 기본적으로 64bit compile

# cd obj-intel64    // 컴파일된 Pintool 확인

 

여기까지 되었다면 정상적으로 설치가 된 것이다.

 

※ 만약, x86 compile 을 하고 싶다면,

# make [~.cpp] TARGET=ia32

 

다음 포스팅에서는 Pintool 과 예제코드 분석에 대해 소개하도록 하겠다. 

'utility' 카테고리의 다른 글

Intel PIN  (2) 2018.06.06
IDAPython Plugin  (0) 2018.06.02
z3 install  (0) 2017.12.15
gef  (0) 2017.01.30
Pwngdb  (0) 2017.01.18
valgrind  (0) 2016.12.20
Posted by woodonggyu

댓글을 달아 주세요

  1. 2018.06.07 18:05  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

IDAPython Plugin

utility 2018. 6. 2. 20:03

IDA 는 편리한 분석을 위한 Python Plugin 을 제공해준다.

설치는 http://code.google.com/p/idapython/downloads/list

 

설치방법은, 파일을 받아 압축을 푼 후

plugins 폴더에 있는 파일을 IDA 설치 폴더에서 - [plugins] 폴더에 복사

python 폴더에 있는 파일을 IDA 설피 폴더에서 - [python] 폴더에 복사

 

위 작업을 거친 후 IDA 실행하면 정상적으로 로드되었다는 메시지를 확인할 수 있다.

IDAPython 을 통해 어떤 것을 할 수 있을지는 examples 폴더 안의 예제 파일들을 참고.

'utility' 카테고리의 다른 글

Intel PIN  (2) 2018.06.06
IDAPython Plugin  (0) 2018.06.02
z3 install  (0) 2017.12.15
gef  (0) 2017.01.30
Pwngdb  (0) 2017.01.18
valgrind  (0) 2016.12.20
Posted by woodonggyu

댓글을 달아 주세요

처음에 정상적으로 동작하지 않는 바이너리와 파일명이 "fragment~" 인 8개의 파일이 제공된다.

파일명으로 미루어보아 fragment 파일들을 이용해 정상적으로 동작시켜야 하는 것임을 추측할 수 있다.

 

직접 fragment 파일을 디어셈블하여 순서를 각각 맞춰 동작시킬 수도 있지만, 

파이썬의 itertools 모듈을 이용하면 이러한 작업을 훨씬 쉽게 수월하게 할 수 있다.

 

itertools 에서 permutations() 를 이용해 순열을 만들 수 있다.

모든 순열의 바이너리를 생성하여 실행하는 코드를 짜고 결과 값을 출력하도록 하면 플래그가 나온다..

 

 

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
32
33
34
35
36
37
38
39
40
41
42
43
44
import itertools
import subprocess
 
file = "FINDFLAG"
 
# read the excutable
broken = open("broken""rb")
bin  = broken.read()
 
broken.close()
 
bin = bin.split('X'*807)
 
if len(broken_list) != 2:
    print "ERROR: binary incorrectly"
 
 
bin_1 = bin[0]
bin_2 = bin[1]
 
fragments = []
 
for i in xrange(19):
 
    frag = open("fragment_" + str(i)+ ".dat""rb")
    fragments.append(frag.read())
 
    frag.close()
 
for order in itertools.permutations(fragments):
 
    order = "".join(order)
 
    f = open(file"wb")
    f.write(bin_1 + bin_2 + fragments)
    f.close()
 
    try:
        res = subprocess.check_output([file], shell=True)
        print res
 
    except:
        continue
 
cs

 

'ctf' 카테고리의 다른 글

[DEFCON 2018 CTF] ELF Crumble  (0) 2018.06.02
[Codegate 2018 CTF] Super Marimo  (0) 2018.02.08
[Codegate 2018 CTF] RedVelvet  (0) 2018.02.08
[Codegate 2018 CTF] BaskinRobins31  (0) 2018.02.08
[BKP 2016 CTF] cookbook  (0) 2017.06.01
[DEFCON 2017 CTF] beatmeonthedl  (0) 2017.05.09
Posted by woodonggyu

댓글을 달아 주세요