#前言
本来这题加了壳,upx -d 也脱不掉,也就没打算做,不过后来我们李老师发了脱壳的命令,也就尝试了下,感觉蛮坑的。记录一下把。

##脱壳

./hide
sudo dd if=/proc/$(pidof hidebak)/mem of=hide_dump1 skip=0x400000  bs=1c count=827392
sudo dd if=/proc/$(pidof hide)/mem of=hide_dump2 skip=7110656  bs=1c count=20480
cat hide_dump1 hide_dump2 > hide_dump

###关于脱壳的补充
我想上几个图应该就能明白了!

可以知道该程序的可执行段为0x400000-0x4ca000以及0x6c8000-0x800000所以我们将这两段内存dump下来即可。

第一个dump还能理解,第二个就有点懵,直接运行脱壳后的程序段错误。-。-
调试hide程序直接退出了,看了下有个ptrace,问了下 跟源程序,下hardware bp,好吧,尝试了下,在hide中下断,来到这里

修改zf标志位寄存器,成功跳转到sub_400a39

然后我就这样被坑了
接着往下走来到0x4009AE,看到了qwb{this_is_wrong_flag},传入sub_400360之后便跳转到这。

说实现我看到xmm1,xmm0之类的寄存器就感到害怕,感觉走上了一条不归路。但是逻辑上没什么问题哈。
好吧,此时我回过头来看hide-dump程序,发现程序起始地址为0x400890-。-!!
突然觉得后背一凉。百度了一下ptrace函数,0代表着PTRACE_TRACEME调试自身???什么意思?父进程调试子进程?难道和我们进行交互的是子进程么?
重新下硬件断点到0x400890,然后我们又可以进入到0x400dd0,感觉好迷!
冷静下来想一想,也许该佛系一点!程序中输出了Enter the flag:\n字符串,那么我们就去寻找它的交叉引用,但是就像我第一次尝试的那样,那段xmm0,xmm1感觉不太像正确的流程,当我对着Enter the flag:\n来一发时,发现他有两处引用的地方。

而且有着同样的正确的逻辑,但是怎样也无法f5,动态调试又没办法运行到这(估计是自己太菜不会这种操作。),硬着头皮,静态逆好了。

可见flag的长度为0x15,应该是qwb{}的格式(q跑哪去了??),然后将剩下的字符串最为参数,调用call sub_4C8CC0 call sub_4C8E50,各三次
其中0x4c8cc0仅对input[0] input[4] input[8] input[12] 进行了变化,sub_4C8E50是一个简单的xor操作,最后将得到的中间串同52 B8 13 7F 35 8C F2 1B F4 63 86 D2 73 4F 1E 31进行比较,可能比较难逆的就是sub_4C8CC0函数了.
这里我主要来逆向分析一下此函数。
首先我们现将v4 和 v3的表达式简化一下

v3=x  大小为4个字节
v4=y
v7='pI1s''Er3P''yR3v''3Y4d'
v3+=(v7[BYTE4(v4)&3]+HIDWORD(v4))^(((v4>>5)^16*v4)+v4)
HIDWORD(v4)+=1735289196
LODWORD(v4)=(v7[(HIDWORD(v4)>>11)&3]+HIDWORD(v4))^(((v3>>5)^16*v3)+v3)+v4

然后结合IDA的宏定义进一步简化。23333
写了一晚上没写出来,这个函数可逆么??感觉是不可逆的?
最后百度了下,找到别人的脚本,本宝宝要睡觉了!
贴上一个绕过反调试的脚本

from idaapi import *from idc import *run_to(0x4009ef)GetDebuggerEvent(WFNE_SUSP, -1)SetRegValue(0x4C8EA0,"RIP")GetDebuggerEvent(WFNE_SUSP, -1)run_to(0x4C8EB3)GetDebuggerEvent(WFNE_SUSP, -1)SetRegValue(0,"RAX")run_to(0x4C8CC0)
#coding=utf-8
import struct
import string
def u32(data):return struct.unpack("<I",data)[0]def p32(data):return struct.pack("<I",data)def u64(data):return struct.unpack("<Q",data)[0]def p64(data):return struct.pack("<Q",data)input1 = '1234567890123456'
input1 = bytearray(input1)
CONST_STR = 's1IpP3rEv3Ryd4Y3'
CONST = 0X676E696C
v4 = 0
v4_4=0
v4_4_arr = [0 for i in range(0,9)]
for i in range(1,9):v4_4_arr[i] = (v4_4_arr[i-1]+CONST)&0XFFFFFFFFdef re_block(byte_arr_8):i = 0v3 = u32(byte_arr_8[0:4])v4 = u32(byte_arr_8[4:8])print 'round', v3, v4for i in range(7,-1,-1):v30 = (v3 << 4) & 0xffffffffv2c = v3 >> 5edx = v30 ^ v2cv30 = (v3 + edx) & 0xffffffffv28 = (v4_4_arr[i+1] >> 11) & 3edx = u32(CONST_STR[v28 * 4:(v28 + 1) * 4])v2c = (v4_4_arr[i+1] + edx) & 0xffffffff  # xxxx# print 'v2c',hex(v2c)print v30 ^ v2cv4 = (v4+0x100000000-(v30 ^ v2c)) & 0xffffffffv30 = (v4 << 4) & 0xffffffffv2c = v4 >> 5edx = v30 ^ v2cv30 = (v4 + edx) & 0xffffffffv28 = v4_4_arr[i] & 3edx = u32(CONST_STR[v28 * 4:(v28 + 1) * 4])v2c = (v4_4_arr[i] + edx) & 0xffffffffv3 = (v3+0x100000000-(v30 ^ v2c)) & 0xffffffffprint 'round',i,v3,v4byte_arr_8[0:4] = p32(v3)byte_arr_8[4:8] = p32(v4)return byte_arr_8
def xor16(byte_arr_16):for i in range(0,16):byte_arr_16[i]^=i
def re_all(str16):byte_arr = bytearray(str16)xor16(byte_arr)#传入整个bytearray,就是传入地址byte_arr[0:8] = re_block(byte_arr[0:8])#传入部分bytearray,就是复制之后再传入byte_arr[8:16] = re_block(byte_arr[8:16])xor16(byte_arr)byte_arr[0:8] = re_block(byte_arr[0:8])byte_arr[8:16] = re_block(byte_arr[8:16])xor16(byte_arr)byte_arr[0:8] = re_block(byte_arr[0:8])byte_arr[8:16] = re_block(byte_arr[8:16])return str(byte_arr)def block(str8):i=0input1=bytearray(str8)v3 = u32(input1[8 * i:8 * i + 4])v4 = u32(input1[8 * i + 4:8 * (i + 1)])v4_4 = 0  ##0000for j in range(0, 8):v30 = (v4 << 4) & 0xffffffffv2c = v4 >> 5edx = v30 ^ v2cv30 = (v4 + edx) & 0xffffffffv28 = v4_4 & 3edx = u32(CONST_STR[v28 * 4:(v28 + 1) * 4])v2c = (v4_4 + edx) & 0xffffffffv3 = ((v30 ^ v2c) + v3) & 0xffffffffv4_4 = (v4_4 + CONST) & 0xffffffffv30 = (v3 << 4) & 0xffffffffv2c = v3 >> 5edx = v30 ^ v2cv30 = (v3 + edx) & 0xffffffffv28 = (v4_4 >> 11) & 3edx = u32(CONST_STR[v28 * 4:(v28 + 1) * 4])v2c = (v4_4 + edx) & 0xffffffff  # xxxxprint v30 ^ v2cv4 = ((v30 ^ v2c) + v4) & 0xffffffffprint 'round', j, v3, v4input1[8 * i:8 * i + 4] = p32(v3)input1[8 * i + 4:8 * (i + 1)] = p32(v4)str8_1=str(input1)return str8_1
def block2(str8):input1 = bytearray(str8)for i in range(0,8):input1[i]=input1[1]^ireturn str(input1)
des = ('52B8137F358CF21B'+'F46386D2734F1E31').decode('hex')
print len(des)print block('12345678').encode('hex')
des1 = '5b90ef3f91b58fe6'.decode('hex')
print re_all(bytearray(des))

##补充
今天才知道原来最后一段是xtea算法,吐一口老血!-。-上网找了xtea的c实现,然后一阵 happy coding后得得到flag
代码如下:

#include <stdio.h>
#include <stdint.h>/* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {unsigned int i;uint32_t v0=v[0], v1=v[1], sum=0, delta=0X676E696C;for (i=0; i < num_rounds; i++) {v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);sum += delta;v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);}v[0]=v0; v[1]=v1;
}void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {unsigned int i;uint32_t v0=v[0], v1=v[1], delta=0X676E696C, sum=delta*num_rounds;for (i=0; i < num_rounds; i++) {v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);sum -= delta;v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);}v[0]=v0; v[1]=v1;
}
void xor(uint32_t v[2]){uint32_t t[2];unsigned int i=0;t[0]=0;t[1]=0;for(i=0;i<4;i++){t[0]+=(((unsigned int)v[0]>>(8*i) & 0xff)^i)<<(8*i);}for(i=4;i<8;i++){t[1]+=(((unsigned int)v[1]>>(8*i) & 0xff)^i)<<(8*i);}v[0]=t[0];v[1]=t[1];
}
void xor2(uint32_t v[2]){uint32_t t[2];unsigned int i=8;t[0]=0;t[1]=0;for(;i<12;i++){t[0]+=(((unsigned int)v[0]>>(8*i) & 0xff)^i)<<(8*i);}for(;i<16;i++){t[1]+=(((unsigned int)v[1]>>(8*i) & 0xff)^i)<<(8*i);}v[0]=t[0];v[1]=t[1];
}
void getflag(uint32_t v[2]){unsigned int i=0;for(i=0;i<4;i++){printf("%c", (v[0]>>(8*i)&0xff));}for(i=0;i<4;i++){printf("%c", (v[1]>>(8*i)&0xff));}printf("\n");
}
//c=[0x52 ,0xB8,0x13 ,0x7F ,0x35 ,0x8C ,0xF2 ,0x1B ,0xF4 ,0x63 ,0x86 ,0xD2 ,0x73 ,0x4F ,0x1E ,0x31]
int main()
{// uint32_t v[2]={0x7c11b952,0x1cf48931};uint32_t const k[4]={0x70493173,0x45723350,0x79523376,0x33593464};unsigned int r=8;//num_rounds建议取值为32uint32_t v[2]={0x7f13b852,0x1bf28c35};uint32_t v2[2]={0xd28663f4,0x311e4f73};//part onexor(v);decipher(r, v, k);xor(v);decipher(r, v, k);xor(v);decipher(r, v, k);printf("解密后的数据:%.8x %.8x\n",v[0],v[1]);getflag(v);//part twoxor2(v2);decipher(r, v2, k);xor2(v2);decipher(r, v2, k);xor2(v2);decipher(r, v2, k);printf("解密后的数据:%.8x %.8x\n",v2[0],v2[1]);getflag(v2);return 0;
}

#总结
至少知道了如何脱壳,如何动静结合的进行调试。以及如何利用python脚本进行反调试的绕过以及控制eip。

XMAN【第二天】hide题解相关推荐

  1. [XUPT_ACM]寒假第二次比赛题解

    写在前面:本次比赛共12题,比赛总体难度相比第一次比赛略有提高,但是整体难度依旧不难,本次比赛打乱了题目,题目难度随机,导致了简单题出题人数减少.本次比赛的题目难度跨度不是特别大,但是题目类型增多,由 ...

  2. 郑州大学“战役杯”第二次比赛题解

    1 公司的Logo 为了感谢河南省八六三软件有限公司对战疫杯ACM在线程序设计竞赛的大力支持,小Y决定为公司制作个logo. logo通常要用在各种不同的场景,因此logo的尺寸必须是可变的.现给你原 ...

  3. 东北大学第二场算法题解报告

    7-1 N个数求和 题解 按照小学学的分数,将输入的分数全部通分,然后分子分母求最大公约数化简 由题目知分数输入的时候均以 分子/分母 给出,我们可以利用 scanf 中的格式符进行输入 代码 #in ...

  4. 集美大学第七届团体程序设计天梯赛第二场排位赛题解

    目录 赛事总结 比赛形式 验题 题型 题目难度 L1 L1 - 1 无职转生之转生成何大佬就要拿到ACMWF----『登峰造极』 题目大意 解题思路 代码 L1 - 2 复读机 思路 代码实现 L1 ...

  5. AST反混淆实战:猿人学爬虫比赛第二题详细题解

    缘起 应星友要求,写下此文,哎,有钱能使鬼推磨. 实战地址: http://match.yuanrenxue.com/match/2 抓包分析 由于谷歌浏览器某些请求不会显示,建议使用火狐浏览器来抓包 ...

  6. 去哪儿2017校园招聘 开发工程师(第二批次)- 题解

    题目链接:点这里. 这套题很有问题,数据有问题,第一题只有83%83\%的数据是对的,第三题只有14%14\%的数据是对的,只能说出题人有点随意,第三题居然能出现n=−1n=-1的这种情况,其实第三题 ...

  7. 数据结构与算法--第二章pro题解

    文章目录 ==模板== --双链表 ==模板==--循环双链表 1.双链表的基本运算 2:整数双链表的基本运算-3 3:整数双链表的基本运算-4 4:循环双链表的基本运算 模板 --双链表 struc ...

  8. SUST-ACM-2019届暑期ACM集训热身赛(第二期)题解

    题目链接:http://sustoj.com/JudgeOnline/contest.php?cid=1035 问题 A: 三角形的面积 三角形成立的条件是:任意两边大于第三边 已知三边求面积: co ...

  9. 牛客网 2018年全国多校算法寒假训练营练习比赛(第二场) 题解

    A-吐泡泡 题目描述 小鱼儿吐泡泡,嘟嘟嘟冒出来.小鱼儿会吐出两种泡泡:大泡泡"O",小泡泡"o". 两个相邻的小泡泡会融成一个大泡泡,两个相邻的大泡泡会爆掉. ...

最新文章

  1. java joptionpanel_JOptionPane用法--java
  2. 开发者账号申请完多久可以用_苹果开发者从0到发布app到apple store
  3. Python 字典推导式 - Python零基础入门教程
  4. python原理与架构_Python:爬虫原理和网页构造
  5. Vue2.0 脚手架代码详解
  6. Eclipse设置:背景与字体大小和xml文件中字体大小调整
  7. jquery的Dom操作查找节点
  8. mongodb mac安装_在Mac OS X上安装MongoDB
  9. 架构实战项目心得(十四):spring-boot结合Swagger2构建RESTful API测试体系
  10. 当我在荒废时间的时候会有多少人在拼命
  11. 【人工智能行业大师访谈4】吴恩达采访Yoshua Bengio
  12. linux下openvpn服务搭建
  13. poi根据模板导出word(包含图片、动态生成表格、合并单元格)(亲测有效)
  14. Linux初探之如何查看帮助文档自学命令
  15. 中国手机企业库存高达6000万,市场正常后或大规模降价促销
  16. html如何找坐标,如何获取现在的坐标
  17. 【EE308FZ Lab2-2】An Amazing Android App for Bobing Game
  18. pytorch学习--UNet模型
  19. 远程同步软件rsync(一)
  20. 小陷胸汤加味方与乳汁淤积

热门文章

  1. grr google
  2. 4.2.1 持久化一个对象
  3. Linux内核之 内核同步
  4. 使用Clover引导黑苹果
  5. MT 103 Single Customer Credit Transfer单笔客户转账
  6. 【Java异常】ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2 JDWP exit erro
  7. 微信小程序:长按图片识别二维码
  8. ARM SMMU学习笔记
  9. go和python组合开发_Web项目可以用Go和Python混合开发吗?
  10. 宝钢洽购沙钢 钢铁航母隐现