티스토리 뷰

리버싱

PinTool Opcode binary 출력 구현

삼전동해커 2022. 2. 14. 16:06
#include "pin.H"
#include <fstream>
#include<iostream>
#include <cstdint>

#define start 0x7FF7B81BC89C
#define end 0x7FF7B81BC8E4



UINT64 icount = 0;

using namespace std;

KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "test.out","A pin tool");

FILE * trace;

//====================================================================
// Analysis Routines
//====================================================================

VOID printip(VOID *ip) {
    fprintf(trace, "%p ", ip);
}
    
VOID printdisassembly(string *s) {
    fprintf(trace, "%s ", s);
}


VOID dump(VOID *ip, UINT32 size) {
    unsigned int i;
    UINT8 opcodeBytes[15];
    //PIN_SafeCopy로 프로그램(openssl)이 사용한 value를 읽고 쓸수 있게 함.
    //opcodeBytes에 ip값을 size만큼 복사
    UINT32 fetched = PIN_SafeCopy(&opcodeBytes[0], ip, size);

    if (fetched != size) {
        fprintf(trace, "*** error fetching instruction at address 0x%lx",(unsigned long)ip);
        return;
    }

    fprintf(trace, "\n\n",size);

    for (i=0; i<size; i++){
        fprintf(trace, " %02x", opcodeBytes[i]); //print the opcode bytes
    }
    fprintf(trace,"\n\n");
        
    fflush(trace);
}

//====================================================================
// Instrumentation Routines
//====================================================================

VOID Instruction(INS ins, void *v) {
    ADDRINT add = INS_Address(ins);
    if(start <= add && add <= end){
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)printip, IARG_INST_PTR, IARG_END);
        INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)printdisassembly, IARG_PTR, new string(INS_Disassemble(ins)), IARG_END);
        INS_InsertCall( ins, IPOINT_BEFORE, (AFUNPTR)dump, IARG_INST_PTR, IARG_UINT32, INS_Size(ins) , IARG_END);
    }
    
}

VOID Fini(INT32 code, VOID *v) {
    printf("count = %ld\n",(long)icount);
}

INT32 Usage(VOID) {
    PIN_ERROR("This Pintool failed\n"
          + KNOB_BASE::StringKnobSummary() + "\n");
    return -1;
}

int main(int argc, char *argv[])
{
    trace = fopen("test.out", "w");

    if (PIN_Init(argc, argv)) return Usage();

    PIN_InitSymbols();
    //PIN_AddInternalExceptionHandler(ExceptionHandler,NULL);
    INS_AddInstrumentFunction(Instruction, 0);
    PIN_AddFiniFunction(Fini, 0);

    // Never returns
    PIN_StartProgram();

    return 0;
}

 

stackoverflow에 올라왔던 질문은 위 코드의 결과만으로 INC와 DEC 명령어가 32비트인지 64비트인지 어떻게 구분할 수 있을까 이다.

해답은 opcode binary 안에 있다.

INC 와 DEC는 32비트에서는 0xFE,0xFF로 표시되고 64비트는 0x40~47,0x48~4F로 표시된다.

따라서 이 부분으로 구분할 수 있을 것 같다.

 

'리버싱' 카테고리의 다른 글

PinTool BBL 개수 출력  (0) 2022.02.15
Taint Analysis란  (0) 2022.02.14
Opcode에 대해  (0) 2022.02.07
DBI PIN tool 사용하기  (0) 2022.01.18
PIN API에 대해  (0) 2022.01.18
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
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
글 보관함