├── 0ops_app ├── 0ops_app.cpp ├── flag ├── makefile ├── makefile.rules ├── testcase │ ├── get_flag │ ├── print_flag │ ├── shell │ └── vuln └── vuln.c ├── CodeCoverage ├── codecoverage.cpp ├── makefile ├── makefile.rules ├── run.sh ├── test │ └── bof1 │ │ ├── bof1.c │ │ └── makefile └── whitelist └── README.md /0ops_app/0ops_app.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "pin.H" 5 | #include 6 | #include 7 | 8 | KNOB KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "output", "specify output file name"); 9 | 10 | int activated = 0; 11 | 12 | INT32 Usage() 13 | { 14 | cerr << "0ops app" << endl; 15 | cerr << endl << KNOB_BASE::StringKnobSummary() << endl; 16 | return -1; 17 | } 18 | 19 | BOOL open_check(THREADID threadIndex, CONTEXT *ctxt, SYSCALL_STANDARD std) 20 | { 21 | char *path = (char*)PIN_GetSyscallArgument(ctxt, std, 0); 22 | int flags = PIN_GetSyscallArgument(ctxt, std, 1); 23 | 24 | return (!flags && !strcmp(path, "flag")); 25 | } 26 | 27 | VOID syscall_check(THREADID threadIndex, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v) 28 | { 29 | int sys_num = PIN_GetSyscallNumber(ctxt, std); 30 | 31 | if (sys_num != 3) { 32 | if (sys_num <= 3 && sys_num > 1) { 33 | if (activated) { 34 | if (open_check(threadIndex, ctxt, std)) 35 | exit(-1); 36 | } 37 | } 38 | } else if (sys_num != 60 && sys_num != 231) { 39 | if (sys_num == 37) { 40 | if (activated) 41 | exit(-1); 42 | activated = 1; 43 | if (mprotect(&activated, 0x1000, 1)) 44 | exit(-1); 45 | } 46 | else { 47 | if (activated) 48 | exit(-1); 49 | } 50 | } 51 | 52 | } 53 | 54 | int main(int argc, char * argv[]) 55 | { 56 | if (PIN_Init(argc, argv)) return Usage(); 57 | 58 | PIN_AddSyscallEntryFunction(syscall_check, 0); 59 | PIN_StartProgram(); 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /0ops_app/flag: -------------------------------------------------------------------------------- 1 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2 | -------------------------------------------------------------------------------- /0ops_app/makefile: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | # 3 | # DO NOT EDIT THIS FILE! 4 | # 5 | ############################################################## 6 | 7 | PIN_ROOT:= /etc/pin 8 | # If the tool is built out of the kit, PIN_ROOT must be specified in the make invocation and point to the kit root. 9 | ifdef PIN_ROOT 10 | CONFIG_ROOT := $(PIN_ROOT)/source/tools/Config 11 | else 12 | CONFIG_ROOT := ../Config 13 | endif 14 | include $(CONFIG_ROOT)/makefile.config 15 | include makefile.rules 16 | include $(TOOLS_ROOT)/Config/makefile.default.rules 17 | 18 | ############################################################## 19 | # 20 | # DO NOT EDIT THIS FILE! 21 | # 22 | ############################################################## 23 | -------------------------------------------------------------------------------- /0ops_app/makefile.rules: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | # 3 | # This file includes all the test targets as well as all the 4 | # non-default build rules and test recipes. 5 | # 6 | ############################################################## 7 | 8 | 9 | ############################################################## 10 | # 11 | # Test targets 12 | # 13 | ############################################################## 14 | 15 | ###### Place all generic definitions here ###### 16 | 17 | # This defines tests which run tools of the same name. This is simply for convenience to avoid 18 | # defining the test name twice (once in TOOL_ROOTS and again in TEST_ROOTS). 19 | # Tests defined here should not be defined in TOOL_ROOTS and TEST_ROOTS. 20 | #TEST_TOOL_ROOTS := 0ops_app 21 | TEST_TOOL_ROOTS := 0ops_app 22 | 23 | # This defines the tests to be run that were not already defined in TEST_TOOL_ROOTS. 24 | TEST_ROOTS := 25 | 26 | # This defines a list of tests that should run in the "short" sanity. Tests in this list must also 27 | # appear either in the TEST_TOOL_ROOTS or the TEST_ROOTS list. 28 | # If the entire directory should be tested in sanity, assign TEST_TOOL_ROOTS and TEST_ROOTS to the 29 | # SANITY_SUBSET variable in the tests section below (see example in makefile.rules.tmpl). 30 | SANITY_SUBSET := 31 | 32 | # This defines the tools which will be run during the the tests, and were not already defined in 33 | # TEST_TOOL_ROOTS. 34 | TOOL_ROOTS := 35 | 36 | # This defines the static analysis tools which will be run during the the tests. They should not 37 | # be defined in TEST_TOOL_ROOTS. If a test with the same name exists, it should be defined in 38 | # TEST_ROOTS. 39 | # Note: Static analysis tools are in fact executables linked with the Pin Static Analysis Library. 40 | # This library provides a subset of the Pin APIs which allows the tool to perform static analysis 41 | # of an application or dll. Pin itself is not used when this tool runs. 42 | SA_TOOL_ROOTS := 43 | 44 | # This defines all the applications that will be run during the tests. 45 | APP_ROOTS := 46 | 47 | # This defines any additional object files that need to be compiled. 48 | OBJECT_ROOTS := 49 | 50 | # This defines any additional dlls (shared objects), other than the 0ops_apptools, that need to be compiled. 51 | DLL_ROOTS := 52 | 53 | # This defines any static libraries (archives), that need to be built. 54 | LIB_ROOTS := 55 | 56 | 57 | ############################################################## 58 | # 59 | # Test recipes 60 | # 61 | ############################################################## 62 | 63 | # This section contains recipes for tests other than the default. 64 | # See makefile.default.rules for the default test rules. 65 | # All tests in this section should adhere to the naming convention: .test 66 | 67 | 68 | ############################################################## 69 | # 70 | # Build rules 71 | # 72 | ############################################################## 73 | 74 | # This section contains the build rules for all binaries that have special build rules. 75 | # See makefile.default.rules for the default build rules. 76 | 77 | # Build the intermediate object file. 78 | #$(OBJDIR)0ops_app$(OBJ_SUFFIX): 0ops_app.cpp 79 | $(OBJDIR)0ops_app$(OBJ_SUFFIX): 0ops_app.cpp 80 | $(CXX) $(TOOL_CXXFLAGS) $(COMP_OBJ)$@ $< 81 | 82 | # Build the tool as a dll (shared object). 83 | #$(OBJDIR)0ops_app$(PINTOOL_SUFFIX): $(OBJDIR)0ops_app$(OBJ_SUFFIX) 84 | $(OBJDIR)0ops_app$(PINTOOL_SUFFIX): $(OBJDIR)0ops_app$(OBJ_SUFFIX) 85 | $(LINKER) $(TOOL_LDFLAGS_NOOPT) $(LINK_EXE)$@ $< $(TOOL_LPATHS) $(TOOL_LIBS) 86 | -------------------------------------------------------------------------------- /0ops_app/testcase/get_flag: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xddaa/pin/4e00490080f32e658c2ed0dde7dbc06779165c73/0ops_app/testcase/get_flag -------------------------------------------------------------------------------- /0ops_app/testcase/print_flag: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xddaa/pin/4e00490080f32e658c2ed0dde7dbc06779165c73/0ops_app/testcase/print_flag -------------------------------------------------------------------------------- /0ops_app/testcase/shell: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xddaa/pin/4e00490080f32e658c2ed0dde7dbc06779165c73/0ops_app/testcase/shell -------------------------------------------------------------------------------- /0ops_app/testcase/vuln: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xddaa/pin/4e00490080f32e658c2ed0dde7dbc06779165c73/0ops_app/testcase/vuln -------------------------------------------------------------------------------- /0ops_app/vuln.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | char buf[32]; 6 | scanf("%s", buf); 7 | printf("%s", buf); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /CodeCoverage/codecoverage.cpp: -------------------------------------------------------------------------------- 1 | #include "pin.H" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | 17 | typedef std::map > MODULE_LIST_T; 18 | typedef std::map BASIC_BLOCKS_INFO_T; 19 | 20 | BASIC_BLOCKS_INFO_T basic_blocks_info; 21 | MODULE_LIST_T module_list; 22 | std::list whitelist; 23 | bool isCrash; 24 | 25 | KNOB KnobOutputPath( 26 | KNOB_MODE_WRITEONCE, 27 | "pintool", 28 | "o", 29 | "./log/test-log.json", 30 | "Specify where you want to store the JSON report" 31 | ); 32 | 33 | KNOB KnobWhitelistPath( 34 | KNOB_MODE_WRITEONCE, 35 | "pintool", 36 | "w", 37 | "whitelist", 38 | "Specify where you want to load whitelist" 39 | ); 40 | 41 | bool is_whitelist(ADDRINT address) 42 | { 43 | for(MODULE_LIST_T::const_iterator it = module_list.begin(); it != module_list.end(); it++) { 44 | ADDRINT low_address = it->second.first; 45 | ADDRINT high_address = it->second.second; 46 | if (std::find(whitelist.begin(), whitelist.end(), it->first) != whitelist.end() && 47 | address >= low_address && address <= high_address) 48 | return true; 49 | } 50 | 51 | return false; 52 | } 53 | 54 | INT32 Usage() 55 | { 56 | std::cerr << "This pintool allows you to generate a JSON report that will contain the address of each basic block executed." << std::endl << std::endl; 57 | std::cerr << std::endl << KNOB_BASE::StringKnobSummary() << std::endl; 58 | return -1; 59 | } 60 | 61 | VOID PIN_FAST_ANALYSIS_CALL handle_basic_block(ADDRINT address_bb) 62 | { 63 | // LOG("[ANALYSIS] BBL Address: " + hexstr(address_bb) + "\n"); 64 | if (basic_blocks_info[address_bb]) 65 | basic_blocks_info[address_bb]++; 66 | else 67 | basic_blocks_info[address_bb] = 1; 68 | } 69 | 70 | VOID trace_instrumentation(TRACE trace, VOID *v) 71 | { 72 | if(!is_whitelist(TRACE_Address(trace))) 73 | return; 74 | 75 | for(BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) 76 | { 77 | // LOG("[INSTRU] BBL Address: " + hexstr(BBL_Address(bbl)) + ", " + hexstr(BBL_NumIns(bbl)) + "\n"); 78 | 79 | BBL_InsertCall( 80 | bbl, 81 | IPOINT_ANYWHERE, 82 | (AFUNPTR)handle_basic_block, 83 | IARG_FAST_ANALYSIS_CALL, 84 | 85 | IARG_ADDRINT, 86 | BBL_Address(bbl), 87 | 88 | IARG_END 89 | ); 90 | } 91 | } 92 | 93 | VOID image_instrumentation(IMG img, VOID * v) 94 | { 95 | ADDRINT module_low_limit = IMG_LowAddress(img), module_high_limit = IMG_HighAddress(img); 96 | const std::string image_path = IMG_Name(img); 97 | std::pair > module_info = std::make_pair( 98 | image_path, 99 | std::make_pair( 100 | module_low_limit, 101 | module_high_limit 102 | ) 103 | ); 104 | 105 | if (IMG_IsMainExecutable(img)) 106 | whitelist.push_front(image_path); 107 | 108 | module_list.insert(module_info); 109 | } 110 | 111 | VOID save_instrumentation_infos() 112 | { 113 | json_t *bbls_info = json_object(); 114 | json_t *bbls_list = json_array(); 115 | json_t *bbl_info = json_object(); 116 | 117 | json_object_set_new(bbls_info, "unique_count", json_integer(basic_blocks_info.size())); 118 | json_object_set_new(bbls_info, "list", bbls_list); 119 | 120 | for(BASIC_BLOCKS_INFO_T::const_iterator it = basic_blocks_info.begin(); it != basic_blocks_info.end(); ++it) 121 | { 122 | bbl_info = json_object(); 123 | json_object_set_new(bbl_info, "address", json_string(hexstr(it->first).c_str())); 124 | json_object_set_new(bbl_info, "count", json_integer(it->second)); 125 | json_array_append_new(bbls_list, bbl_info); 126 | } 127 | 128 | json_t *modules = json_object(); 129 | json_t *modules_list_ = json_array(); 130 | 131 | json_object_set_new(modules, "unique_count", json_integer(module_list.size())); 132 | json_object_set_new(modules, "list", modules_list_); 133 | 134 | for(MODULE_LIST_T::const_iterator it = module_list.begin(); it != module_list.end(); ++it) 135 | { 136 | json_t *mod_info = json_object(); 137 | json_object_set_new(mod_info, "path", json_string(it->first.c_str())); 138 | json_object_set_new(mod_info, "low_address", json_string(hexstr(it->second.first).c_str())); 139 | json_object_set_new(mod_info, "high_address", json_string(hexstr(it->second.second).c_str())); 140 | json_array_append_new(modules_list_, mod_info); 141 | } 142 | 143 | json_t *root = json_object(); 144 | json_object_set_new(root, "crash", json_boolean(isCrash)); 145 | json_object_set_new(root, "basic_blocks_info", bbls_info); 146 | json_object_set_new(root, "modules", modules); 147 | 148 | FILE* f = fopen(KnobOutputPath.Value().c_str(), "w"); 149 | json_dumpf(root, f, JSON_COMPACT | JSON_ENSURE_ASCII); 150 | fclose(f); 151 | } 152 | 153 | VOID this_is_the_end(INT32 code, VOID *v) 154 | { 155 | save_instrumentation_infos(); 156 | } 157 | 158 | BOOL crash(THREADID tid, INT32 sig, CONTEXT *ctxt, BOOL hasHandler, const EXCEPTION_INFO *pExceptInfo, VOID *v) 159 | { 160 | isCrash = true; 161 | return true; 162 | } 163 | 164 | void get_whitelist() 165 | { 166 | fstream fp; 167 | fp.open(KnobWhitelistPath.Value().c_str(), ios::in); 168 | 169 | if (!fp) 170 | cerr << "No whitelist" << endl; 171 | else { 172 | char buf[100]; 173 | while (fp.getline(buf, 100)) { 174 | std::string white_module(buf); 175 | whitelist.push_back(white_module); 176 | } 177 | } 178 | } 179 | 180 | int main(int argc, char *argv[]) 181 | { 182 | if(PIN_Init(argc,argv)) 183 | return Usage(); 184 | 185 | get_whitelist(); 186 | TRACE_AddInstrumentFunction(trace_instrumentation, 0); 187 | IMG_AddInstrumentFunction(image_instrumentation, 0); 188 | PIN_AddFiniFunction(this_is_the_end, 0); 189 | PIN_InterceptSignal(SIGSEGV, crash, 0); 190 | 191 | PIN_StartProgram(); 192 | 193 | return 0; 194 | } 195 | -------------------------------------------------------------------------------- /CodeCoverage/makefile: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | # 3 | # DO NOT EDIT THIS FILE! 4 | # 5 | ############################################################## 6 | 7 | PIN_ROOT:= /etc/pin 8 | # If the tool is built out of the kit, PIN_ROOT must be specified in the make invocation and point to the kit root. 9 | ifdef PIN_ROOT 10 | CONFIG_ROOT := $(PIN_ROOT)/source/tools/Config 11 | else 12 | CONFIG_ROOT := ../Config 13 | endif 14 | include $(CONFIG_ROOT)/makefile.config 15 | include makefile.rules 16 | include $(TOOLS_ROOT)/Config/makefile.default.rules 17 | 18 | ############################################################## 19 | # 20 | # DO NOT EDIT THIS FILE! 21 | # 22 | ############################################################## 23 | -------------------------------------------------------------------------------- /CodeCoverage/makefile.rules: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | # 3 | # This file includes all the test targets as well as all the 4 | # non-default build rules and test recipes. 5 | # 6 | ############################################################## 7 | 8 | 9 | ############################################################## 10 | # 11 | # Test targets 12 | # 13 | ############################################################## 14 | 15 | ###### Place all generic definitions here ###### 16 | 17 | # This defines tests which run tools of the same name. This is simply for convenience to avoid 18 | # defining the test name twice (once in TOOL_ROOTS and again in TEST_ROOTS). 19 | # Tests defined here should not be defined in TOOL_ROOTS and TEST_ROOTS. 20 | TEST_TOOL_ROOTS := codecoverage 21 | 22 | # This defines the tests to be run that were not already defined in TEST_TOOL_ROOTS. 23 | TEST_ROOTS := 24 | 25 | # This defines a list of tests that should run in the "short" sanity. Tests in this list must also 26 | # appear either in the TEST_TOOL_ROOTS or the TEST_ROOTS list. 27 | # If the entire directory should be tested in sanity, assign TEST_TOOL_ROOTS and TEST_ROOTS to the 28 | # SANITY_SUBSET variable in the tests section below (see example in makefile.rules.tmpl). 29 | SANITY_SUBSET := 30 | 31 | # This defines the tools which will be run during the the tests, and were not already defined in 32 | # TEST_TOOL_ROOTS. 33 | TOOL_ROOTS := 34 | 35 | # This defines the static analysis tools which will be run during the the tests. They should not 36 | # be defined in TEST_TOOL_ROOTS. If a test with the same name exists, it should be defined in 37 | # TEST_ROOTS. 38 | # Note: Static analysis tools are in fact executables linked with the Pin Static Analysis Library. 39 | # This library provides a subset of the Pin APIs which allows the tool to perform static analysis 40 | # of an application or dll. Pin itself is not used when this tool runs. 41 | SA_TOOL_ROOTS := 42 | 43 | # This defines all the applications that will be run during the tests. 44 | APP_ROOTS := 45 | 46 | # This defines any additional object files that need to be compiled. 47 | OBJECT_ROOTS := 48 | 49 | # This defines any additional dlls (shared objects), other than the pintools, that need to be compiled. 50 | DLL_ROOTS := 51 | 52 | # This defines any static libraries (archives), that need to be built. 53 | LIB_ROOTS := 54 | 55 | 56 | ############################################################## 57 | # 58 | # Test recipes 59 | # 60 | ############################################################## 61 | 62 | # This section contains recipes for tests other than the default. 63 | # See makefile.default.rules for the default test rules. 64 | # All tests in this section should adhere to the naming convention: .test 65 | 66 | 67 | ############################################################## 68 | # 69 | # Build rules 70 | # 71 | ############################################################## 72 | 73 | # This section contains the build rules for all binaries that have special build rules. 74 | # See makefile.default.rules for the default build rules. 75 | 76 | # Build the intermediate object file. 77 | $(OBJDIR)codecoverage$(OBJ_SUFFIX): codecoverage.cpp 78 | $(CXX) $(TOOL_CXXFLAGS) -ljansson $(COMP_OBJ)$@ $< 79 | 80 | # Build the tool as a dll (shared object). 81 | $(OBJDIR)codecoverage$(PINTOOL_SUFFIX): $(OBJDIR)codecoverage$(OBJ_SUFFIX) 82 | $(LINKER) $(TOOL_LDFLAGS_NOOPT) $(LINK_EXE)$@ $< $(TOOL_LPATHS) $(TOOL_LIBS) -ljansson 83 | -------------------------------------------------------------------------------- /CodeCoverage/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -z $1 ]; then 4 | echo "Usage: ./run " 5 | exit 6 | fi 7 | 8 | make 9 | 10 | if [ -z $2 ]; then 11 | binary=`basename $1` 12 | date=`date +%T-%m-%d` 13 | pin -t obj-ia32/codecoverage.so -o "log/"$binary"_"$date -- $1 14 | else 15 | pin -t obj-ia32/codecoverage.so -o "log/"$2 -- $1 16 | cat "log/"$2 | python -m json.tool | less 17 | fi 18 | -------------------------------------------------------------------------------- /CodeCoverage/test/bof1/bof1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void foo(char *bar) 5 | { 6 | char c[12]; 7 | 8 | strcpy(c, bar); // no bounds checking 9 | fflush(stdout); 10 | } 11 | 12 | int main(int argc, char **argv) 13 | { 14 | char buf[4096]; 15 | 16 | printf("input: "); 17 | fgets(buf,4096,stdin); 18 | foo(buf); 19 | } 20 | -------------------------------------------------------------------------------- /CodeCoverage/test/bof1/makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -fno-stack-protector bof1.c -o ../../benchmark/bof1 3 | -------------------------------------------------------------------------------- /CodeCoverage/whitelist: -------------------------------------------------------------------------------- 1 | /lib/i386-linux-gnu/libc.so.6 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Intel Pin Tools basic usage 2 | 3 | ## Building Environment 4 | 下載 [Intel Pin Tools](https://software.intel.com/en-us/articles/pintool-downloads) 5 | 解壓縮就可以使用 不用另外安裝 6 | 將解壓縮出來的資料夾 加入 $PATH 7 | 8 | ## What Is Pin 9 | pin 是 intel 開發的一個 binary analysis framework 10 | 支援 x86/x64 & windows/linux/mac 11 | pin 提供許多分析 binary 用的 api 12 | 使用者可以用 C/C++ 呼叫 api 來撰寫自己的 pintool 13 | 14 | ## Run Sample Code 15 | *source/tools* 是 pintools 的預設路徑 16 | 底下已經有一些現成 pintools 可以使用 17 | 18 | 根據 README 的步驟來操作: 19 | `cd source/tools/SimpleExamples` 20 | `make obj-ia32/opcodemix.so` // 編完的 pintool 是一個 share object 存在 obj-ia32 底下 21 | `pin -t obj-ia32/opcodemix.so -- /bin/ls` // 用 pintool 分析 /bin/ls 22 | 分析結果在 opcodemix.out 23 | 24 | ## Write Our Pintool 25 | 複製 *source/tools/MyPinTool* 稍作修改 26 | 27 | *MyPinTool.cpp*: 主要的程式碼 撰寫自己要對 binary 做的分析行為 28 | *makefile*: 理論上不需要更改到 makefile 29 | *makefile.rule*: 覆寫編譯時的設定 客製化自己的需求 30 | 31 | 簡單介紹一下 sample code 用到的 function 32 | 33 | `Knob`: 這個類別指的是執行 pin 指令時的參數, 可以自訂一些預設值 34 | `PIN_init()`: 將執行參數傳遞給 pin tool 35 | `INS`: INS 類別代表 asm 指令 36 | `INS_AddInstrumentFunction`: 定義分析 INS 的 callback 37 | `TRACE`: TRACE 類別是 JIT 時分析定義的一種指令區塊 有一個進入點和數個離開點 38 | `TRACE_AddInstrumentFunction`: 定義 TRACE 的 callback 39 | `PIN_AddThreadStartFunction`: 定義偵測到有另一個 thread start 的 callback 40 | `PIN_AddFiniFunction`: 定義程式結束的 callback 41 | `PIN_StartProgram`: 程式開始 42 | 43 | PIN 的詳細文件可以參考: [Pin 2.14 User Guide](https://software.intel.com/sites/landingpage/pintool/docs/71313/Pin/html/) 44 | --------------------------------------------------------------------------------