본문 바로가기

Reversing/▷ ETC

Stack protector use Pintools

#include <stdio.h>

int main()
{
	char buf[100];
	printf("Plz input >> \n");
	fflush(stdout);
	read(0, buf, 1024);
	printf("%s\n", buf);

	return 0;
}

//gcc -o test test.c -fno-stack-protector

Ubuntu 16.04 64bit


#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include "pin.H"
 
using namespace std;
FILE *fp = NULL;

#define START 0x4005f6
#define END 0x400644

static UINT16       _tabAddr[0x10000];
static std::string  _tabStr[0x10000];
static size_t         timerJiffies;

long int check = 0;

/*void getRegister(CONTEXT *ctxt, std::string insDis)
{
	std::cout << insDis << std::endl;
   fprintf(stdout, "rax: 0x%lx\nrbx: 0x%lx\nrcx: 0x%lx\nrdx: 0x%lx\nrsi: 0x%lx\nrdi: 0x%lx\nrbp: 0x%lx\nrsp: 0x%lx\n",
   PIN_GetContextReg(ctxt, REG_RAX),
   PIN_GetContextReg(ctxt, REG_RBX),
   PIN_GetContextReg(ctxt, REG_RCX),
   PIN_GetContextReg(ctxt, REG_RDX),
   PIN_GetContextReg(ctxt, REG_RSI),
   PIN_GetContextReg(ctxt, REG_RDI),
   PIN_GetContextReg(ctxt, REG_RBP),
   PIN_GetContextReg(ctxt, REG_RSP));
}*/

void Trace(UINT64 prevAddr, UINT64 insAddr, UINT64 nextAddr, std::string insDis, CONTEXT *ctxt)
{
	timerJiffies++;

	if (insAddr > 0x700000000000)
		return;

	if (_tabAddr[insAddr ^ 0x400000] == 0xffff)
		return;

	_tabAddr[insAddr ^ 0x400000] += 1;
	_tabStr[insAddr ^ 0x400000] = insDis;
	std::cout << insDis << std::endl;
	if(!insDis.compare("ret ")){
		/*fprintf(stdout, "rax: 0x%lx\nrbx: 0x%lx\nrcx: 0x%lx\nrdx: 0x%lx\nrsi: 0x%lx\nrdi: 0x%lx\nrsp: 0x%lx\n",
		PIN_GetContextReg(ctxt, REG_RAX),
		PIN_GetContextReg(ctxt, REG_RBX),
		PIN_GetContextReg(ctxt, REG_RCX),
		PIN_GetContextReg(ctxt, REG_RDX),
		PIN_GetContextReg(ctxt, REG_RSI),
		PIN_GetContextReg(ctxt, REG_RDI),
		PIN_GetContextReg(ctxt, REG_RSP));*/
		long int check2 = PIN_GetContextReg(ctxt, REG_RBP);
		fprintf(stdout, "SFP = %lx\n", check);
		fprintf(stdout, "RBP = %lx\n", check2);
		if(check != check2)
		{
			puts("*** stack smashing detected ***");
			exit(0);
		}

	}
	else if(!insDis.compare("push rbp")) {
		check = PIN_GetContextReg(ctxt, REG_RBP);
		fprintf(stdout, "SFP = %lx\n", check);
	}
}

static VOID RecordMem(VOID * ip, CHAR r, VOID * addr, INT32 size, BOOL isPrefetch)
{
    fprintf(fp, "%p [%c] %p (%d)\n", ip, r, addr, size);
}


void printip(void* ip)
{
         printf("%p:\t",ip);
}
 
void Instruction(INS ins, VOID* v)
{
	long int a = (long int)INS_Address(ins);
	//long int b = (long int)INS_Opcode(ins);
    if(START<=a && a<=END)
    {
       	INS_InsertCall(ins,IPOINT_BEFORE, (AFUNPTR)printip, IARG_INST_PTR, IARG_END);
		if (INS_IsMemoryRead(ins))
    	{
        	INS_InsertCall(
            ins, IPOINT_BEFORE, (AFUNPTR)RecordMem,
            IARG_INST_PTR,
            IARG_UINT32, 'R',
            IARG_MEMORYREAD_EA,
            IARG_MEMORYREAD_SIZE,
            IARG_BOOL, INS_IsPrefetch(ins),
            IARG_END);
    	}
    	else if(INS_IsMemoryWrite(ins))
    	{
        	INS_InsertCall(
            ins, IPOINT_BEFORE, (AFUNPTR)RecordMem,
            IARG_INST_PTR,
            IARG_UINT32, 'W',
            IARG_MEMORYWRITE_EA,
            IARG_MEMORYWRITE_SIZE,
            IARG_BOOL, INS_IsPrefetch(ins),
            IARG_END);
    	}
		
		INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)Trace,
		IARG_ADDRINT, INS_Address(INS_Prev(ins)),
    	IARG_ADDRINT, INS_Address(ins),
    	IARG_ADDRINT, INS_Address(INS_Next(ins)),
    	IARG_PTR, new string(INS_Disassemble(ins)),
		IARG_CONTEXT,
    	IARG_END);
		
		/*if(b!=XED_ICLASS_PUSH && b!=XED_ICLASS_MOV && b!=XED_ICLASS_SUB && b!=XED_ICLASS_LEA && b!=XED_ICLASS_LEAVE) {
		INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)getRegister, 
		IARG_PTR, new string(INS_Disassemble(ins)), 
		IARG_CONTEXT, 
		IARG_END);
		}*/
	}
}
 
void Fini(INT32 code, VOID *v)
{
	cout << "[Finish]" << endl;
}
 
int main(int argc,char* argv[])
{
    PIN_Init(argc,argv);

	std::cout << "------------------" << std::endl;
    std::cout << "Addr\t\tDisass" << std::endl;
 	fp = fopen("./log.txt", "w");
    INS_AddInstrumentFunction(Instruction,0);
    PIN_AddFiniFunction(Fini,0);
 
    PIN_StartProgram();
    return 0;
}

main 주소로 범위를 잡아놓고 address 와 disassemble string 을 출력해서 만약 Push rbp 가 실행됐을때, rbp 값(sfp)을 check 변수에 저장해 둔다. 

후에 ret 명령어가 실행되기전 rbp 값(sfp)을 추출하고 check2에 저장해 sfp 값이 변조되었는지 확인해 변조되었다면 stack smashing을 일으켜 exit 시킨다.

Pintool 정말 좋은 tool 이지만 쓰기 너무어렵다... 메뉴얼을 보면 되지만.. 영어공부를 열심히 해야겠다.


[실행 예제 1] gyeongje@gyeongjepc:~/Desktop/pin/source/tools/MyPinTool/obj-intel64$ ~/Desktop/pin/pin -t ./gyeongje.so -- ~/test ------------------ Addr Disass 0x4005f6: push rbp SFP = 400650 0x4005f7: mov rbp, rsp 0x4005fa: sub rsp, 0x70 0x4005fe: mov edi, 0x4006d4 0x400603: call 0x4004b0 Plz input >> 0x400608: mov rax, qword ptr [rip+0x200a39] 0x40060f: mov rdi, rax 0x400612: call 0x4004e0 0x400617: lea rax, ptr [rbp-0x70] 0x40061b: mov edx, 0x400 0x400620: mov rsi, rax 0x400623: mov edi, 0x0 0x400628: mov eax, 0x0 0x40062d: call 0x4004c0 --- AAAA ---- Gyeongje ---- BBBB 0x400632: lea rax, ptr [rbp-0x70] 0x400636: mov rdi, rax 0x400639: call 0x4004b0 --- AAAA ---- Gyeongje ---- BBBB 0x40063e: mov eax, 0x0 0x400643: leave 0x400644: ret SFP = 400650 RBP = 400650 [Finish] [실행 예제 2] gyeongje@gyeongjepc:~/Desktop/pin/source/tools/MyPinTool/obj-intel64$ ~/Desktop/pin/pin -t ./gyeongje.so -- ~/test ------------------ Addr Disass A0x4005f6: push rbp SFP = 400650 0x4005f7: mov rbp, rsp 0x4005fa: sub rsp, 0x70 0x4005fe: mov edi, 0x4006d4 0x400603: call 0x4004b0 Plz input >> 0x400608: mov rax, qword ptr [rip+0x200a39] 0x40060f: mov rdi, rax 0x400612: call 0x4004e0 0x400617: lea rax, ptr [rbp-0x70] 0x40061b: mov edx, 0x400 0x400620: mov rsi, rax 0x400623: mov edi, 0x0 0x400628: mov eax, 0x0 0x40062d: call 0x4004c0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 0x400632: lea rax, ptr [rbp-0x70] 0x400636: mov rdi, rax 0x400639: call 0x4004b0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ?? 0x40063e: mov eax, 0x0 0x400643: leave 0x400644: ret SFP = 400650 RBP = 4141414141414141 *** stack smashing detected ***


'Reversing > ▷ ETC' 카테고리의 다른 글

Peview 패치  (0) 2018.03.31
Arm, mips, ppc등 cross compile and excution  (1) 2018.03.12
Side Channel Attack using gdb  (0) 2018.02.16
hsdecomp error modification  (0) 2018.02.06
objdump 사용법  (1) 2018.02.01