当前位置: 首页 > news >正文

信息网站开发网络公司/百度客服平台

信息网站开发网络公司,百度客服平台,采购信息发布,网上翻译网站做译员https://blog.csdn.net/whklhhhh/article/details/79275932 1625-5 王子昂 总结《2018年2月3日》 【连续第491天总结】 A. PinTools编写、win32程序的适配 B. 之前编译好了ManualExamples中的inscount,但是0、1、2的计算都很不准确,高达几百万且波动…

https://blog.csdn.net/whklhhhh/article/details/79275932

1625-5 王子昂 总结《2018年2月3日》 【连续第491天总结】
A. PinTools编写、win32程序的适配
B.
之前编译好了ManualExamples中的inscount,但是0、1、2的计算都很不准确,高达几百万且波动极大,所以没法通过例程的指令计数来爆破

于是只好自己参照API来修改
感觉很久没有从零开始查文档写程序啦~
官方的例程真的很充分,文档也特别详细

基础介绍

PinTools文档:
https://software.intel.com/sites/landingpage/pintool/docs/81205/Pin/html/index.html

Linux

Pin tool由int main(int argc, char * argv[])函数开始,由NMAKE编译选项编译成特定的动态链接库,如果要编译自己的动态链接库,在Nmakefile文件中把要编译的动态链接库名字加到COMMON_TOOLS=后面,使用..\nmake.bat TARGET=ia32 xxx.dll命令进行编译。

Windows

在makefile.rules中找到

TEST_TOOL_ROOTS := inscount0_win_stdout
来修改,添加目标

另外obj-ia32中的库只能对32位的程序(无论是elf还是exe使用),对于64位的程序则需要编译出obj-intel64的版本

make TARGET=ia32/intel64 可以指定目标版本

如果在程序中要使用符号,要调用PIN_InitSymbols();来初始化PIN_Init(argc, argv)

PIN tool分四种插装粒度

  • 指令级插桩(instruction instrumentatio),通过函数INS_AddInstrumentFunctio实现。

  • 轨迹级插装(trace instrumentation),通过函数TRACE_AddInstrumentFunction实现。(貌似就是基本块插装)

  • 镜像级插装(image instrumentation),使用IMG_AddInstrumentFunction函数,由于其依赖于符号信息去确定函数边界,因此必须在调用PIN_Init之前调用PIN_InitSymbols。

  • 函数级的插装(routine instrumentation),使用RTN_AddInstrumentFunction函数。函数级插装比镜像级插装更有效,因为只有镜像中的一小部分函数被执行。

其中,IMG_AddInstrumentFunction和RTN_AddInstrumentFunction需要先调用PIN_InitSymbols(),来分析出符号。在无符号的程序中,IMG_AddInstrumentFunction和RTN_AddInstrumentFunction无法分析出相应的需要插装的块。
在各种粒度的插装函数调用时,可以添加自己的处理函数在代码中,程序被加载后,在被插装的代码运行时,自己添加的函数会被调用。

INS_AddInstrumentFunctio、TRACE_AddInstrumentFunction、IMG_AddInstrumentFunction、RTN_AddInstrumentFunction指定的回调函数只有在相应的代码被分析到时才会被调用,即分析到一次只被调用一次,但程序运行过程中一般不再被调用,但INS_InsertCall之类的程序添加的函数,是在相应的代码位置添加函数,根据程序运行的情况,会被多次调用。

在INS_AddInstrumentFunctio指令级插装的代码中,只有在INS_AddInstrumentFunctio指定的函数被调用时INS指令才有效,在INS_InsertCall函数中,INS无效。

从API中可以看出
Img->Sec->Rtn->Ins,相邻的级别是可以相互转换的
例如在Img中可以通过IMG_SecHead(img)来得到首个section,再通过section遍历其中的rtn即可得到期望的主函数模块了

编写心得

image对应模块,即文件(exe/dll)
routine对应的是可识别的函数,对于无符号的exe中的用户模块,似乎通常会识别出unnamedImageEntryPoint.text两个函数,其中前者为start函数,后者为真正的main函数
instruction对应的是汇编指令,没什么好说的
trace不明白是啥来的,之后有空再试用一下

如果直接由IMG_Entry的地址和RTN_FindByAddress的越级方式获取,仅能得到一个RTN,而不是所有的RTN链表
刚开始因为没有sec的级别所以没注意,在这上卡了不少时间
start()所在的RTN中运行代码跟输入几乎无关,似乎仅在输入输出流会有几十个指令的区别

编写思路

proccount的例程中可以看出 ,用户模块的代码仅有几万,大量代码都是各种系统库的调用
那么目标是排除系统库,仅保留用户模块、即主程序的指令计数

为了尽量加快速度,我选择了在IMG级别插第一个桩,刚开始是校验地址是否为0x401000,或者模块名是否为程序名,但是一方面编写比较复杂,另一方面无法保证是否存在地址重定向,或是ASLR之类修改地址

在查找API的时候偶然发现有IMG_IsMainExecutable检查img是否为主程序,检查为我们的需求量身定做

通过它来判断截下的img是否为需要的主程序,如果不是就直接放过,是的话则进行指令插桩计数
刚开始直接通过地址取rtn,发现每次拿到的都是start,并且链接不到后一个rtn

现在想来应该是FindByAddress这个API本来拿到的就是单独一个rtn
后来发现IMG中有通过SEC来转RTN的API,这样就能取到整个RTN链了

得到RTN 以后遍历INS,插入计数的桩最后输出即可

代码

#include <fstream>
#include <iomanip>
#include <iostream>
#include <string.h>
#include "pin.H"static UINT64 icount = 0;
static string name;
ofstream outFile;VOID docount()
{icount++;
}VOID Routine(IMG img, VOID *v)
{if(IMG_IsMainExecutable(img)){SEC sec = IMG_SecHead(img);RTN rtn = (SEC_RtnHead(sec));{RTN_Open(rtn);name = RTN_Name(rtn);for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)){INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_END);}RTN_Close(rtn);}}
}VOID Fini(INT32 code, VOID *v)
{outFile << name << endl << icount << endl;
}INT32 Usage()
{cout<<"Please input the win32 exe";return -1;
}int main(int argc, char * argv[])
{PIN_InitSymbols();outFile.open("inscount1_win.out", );if (PIN_Init(argc, argv)) return Usage();IMG_AddInstrumentFunction(Routine, 0);PIN_AddFiniFunction(Fini, 0
);PIN_StartProgram();return 0;
}
  • 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

虽然其实相比iscount来说改动其实很小,不过对于PinTools的API理解总算是入了门 。经过修改后的程序仅仅会取main所在的一个rtn,还有一些遍历rtn、sec的代码因为在大部分程序中应该都无用所以略去了

爆破用的python2代码:

#coding=utf-8
import popen2
import stringINFILE = "test"
CMD = r"E:\ctf\pin\pin.exe -t E:\ctf\pin\source\tools\ManualExamples\obj-ia32\inscount1_win.dll -- F:\ctf\Whale\CrackMe\CrackMe.exe <" + INFILE
choices = "01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%&'()*+,-./:;<=>?@[\]^_`{|}~"
# 重复放置0是为了保证如果0正确,有9->0这样错误到正确的变化,能正确捕获def execlCommand(command):global ffin,fout = popen2.popen2(command)fin.readline()# fin.readline()result1 = fin.readline()#获取程序自带打印信息,wrong或者correctprint(result1)if('Failed' not in result1):#输出Correct时终止循环f = 0result2 = fin.readline()#等待子进程结束,结果输出完成fin.close()def writefile(data):fi = open(INFILE,'w')fi.write(data)fi.close()def pad(data, n, padding):return data + padding * (n - len(data))flag = ''
# flag = '#7Ff@(24'
f = 1
while(f):l = 0#初始化计数器for i in choices:key = flag + i#测试字符串print(">",key)writefile(key)execlCommand(CMD)fi = open('./inscount1_win.out', 'r')# 管道写入较慢,读不到内容时继续尝试读while(1):try:# n = int(fi.read().split(' ')[1], 10)fi.readline()n = int(fi.readline())breakexcept IndexError:continuefi.close()print(n)if(n-l > 0 and l):#如果两次运行指令差别过大,说明字符正确flag += ibreakelse:l = nprint(flag)
  • 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

后记

虽然总算是能跑起来了,但是由于Windows程序加载库过于多的原因,PinTools注入的速度特别慢
整个程序大概保持在每个字符花费2s的速度,对于实验程序CrackMe的47位flag来说,得到flag的每一位字符平均需要一分钟以上 总耗时还是有点夸张的

思考了一下,耗时过久有两个因素

  • 插桩参考了proccount例程,使用的是INS级的插桩,相比BBL代码块级的指令计数会慢许多。但是Img->Sec->Rtn->Ins的链中不知道该怎么引入Trace->Bbl,之后尝试一下Trace级别的插桩
  • Python逐字符+管道+PinTools三者都是比较耗时的程序,可以考虑多线程来批量运行PinTools。不过由于PinTools的原理是注入Dll,所以有点担心多线程的dll可能会彼此影响,从而得到不正确的结果。说多无益,明天跑一遍看看吧

C. 明日计划
PinTools多线程爆破尝试
Trace级理解

http://www.lbrq.cn/news/1606015.html

相关文章:

  • 医疗器械网站建设方案/地推扫码平台
  • 专业做婚庆的网站/快速优化系统
  • 好优化网站设计/成全高清免费观看mv
  • 合肥网站设计品牌/百度推广登陆首页
  • 网络公司 网站源码/企业管理培训班哪个好
  • 做网站要买什么服务器/互联网项目推广平台有哪些
  • 贵州住房建设厅网站/网络营销岗位招聘信息
  • 体育馆做网站公司/不属于网络推广方法
  • 中山技术支持中山网站建设/酒店推广渠道有哪些
  • 学习网站建设/深圳网络推广外包
  • 安阳做网站公司/网络营销和网站推广的区别
  • wordpress评论 图片/谷歌seo是指什么意思
  • 服务平台管理系统/seo综合排名优化
  • python适合网站开发吗/网络推广一个月工资多少
  • 城乡规划师证报考条件/广州seo推荐
  • 全球疫情防控最新消息/东莞网络优化排名
  • 那个网站都有做莱的图片/企业网站的主要类型有
  • 无锡企业免费建站/2023年5月最新疫情
  • 桂林两江四湖景区/武汉seo网站优化
  • WordPress全站展示/58同城关键词怎么优化
  • 自驾游网站建设/湖南seo博客seo交流
  • 企业网站建设背景/seo网络推广报价
  • 做网站百度云/合肥网络公司
  • 永登网站设计与建设/怎么创建自己的网站
  • 公安备案网站老是通不过/媒体发稿推广
  • 建设自己的淘宝优惠券网站/搜索引擎优化搜索优化
  • 怎样做网站的源代码/成品网站源码
  • 在西部数码做的企业网站不能与阿里巴巴网站相连接/市场营销计划书模板
  • 外贸在线网站建站/网站引流推广
  • 怎么做网站的思维导图/旅游营销推广方案
  • 机器人抓取流程介绍与实现——机器人抓取系统基础系列(七)
  • .env 文件
  • Python编程基础与实践:Python基础数据类型入门
  • cmd怎么取消关机命令
  • 【多模态】DPO学习笔记
  • 大模型结构比较