安询杯 reverse ezr3 复现

文章描述了一个对加壳程序进行逆向工程的过程,包括识别UPX壳、手动脱壳、动态调试以理解加密算法。通过分析V函数、auth数组和memstore数组的操作,揭示了位操作和特定格式校验,以及解密步骤,最终实现了对加密数据的还原。
摘要由CSDN通过智能技术生成

分析过程

首先使用IDA打开,发现只有几个函数,应该是加壳了,但是使用PE工具,查不到壳信息,用010editor 打开,发现4.02,应该是UPX的壳,但是特征被改了,所以导致无法脱壳,修改回UPX后,使用upx-d,成功脱壳。

再次使用IDA打开,入口有个V函数,进去看下
在这里插入图片描述
这里V的返回值是没有使用过的,所以直接改成void,这里有两个数组,一个auth,一个memstore
在这里插入图片描述
这里的操作都是对V3进行操作,也就是auth数组的操作,那我们不关心内部的具体实现,直接动态把auth数组dump出来,这里有个反调试,ptrace直接nop掉,传到手机上,IDA附加,main里面打个断点,把处理过的auth数字打印出来

auth=[0x0003B148, 0x000D2CAE, 0x0003A1FB, 0x00044F40, 0x000472DE, 0x0000CCC0, 0x00001888, 0x00003B80, 0x000702F7, 0x000C745C, 0x000658E0, 0x000858D4, 0x0000D5BD, 0x00004860, 0x0014F410, 0x0002CB9F, 0x000321DB, 0x0014D534, 0x00025DA0, 0x0006898C, 0x00123D56, 0x00058E4D, 0x00050CF8, 0x00005D64, 0x000978BA, 0x0008F290, 0x0003B568, 0x00054696, 0x00094C12, 0x0001021F, 0x000DBACB, 0x00049680, 0x0002FABD, 0x000F2B58, 0x0012D23C, 0x0014AED3]

在这里插入图片描述
这里进行了一堆操作,也看不懂,也没有什么输出,就动态一直调呗,调试的时候看下内存中自己输入的值,大概就是对格式的校验,需要SYC{}的格式才会走到后面的计算函数,在这里插入图片描述
进入p函数,这里IDA的识别有点问题,修正一下V8数组,更好看
在这里插入图片描述
这里有两部分的操作,第一部分的关键操作:

v3 = ((unsigned __int8)v8[v1] >> 4) | (16 * (unsigned __int8)v8[v1]);
      v8[v1] = ((unsigned __int8)v8[v1] >> 4) | (16 * v8[v1]);
      v8[v1++] = v2[strlen(v8)] ^ v3;

在这里,一开始不是很懂,在这里v8[v1] >> 4,就是右移四位,如果 v8[v1] 为 1100 1010,那么右移 4 位后的结果为 0000 1100,(16 * (unsigned __int8)v8[v1])是左移四位,在二进制数中,乘以 2 的幂(如 2、4、8、16 等)相当于将数的二进制位向左移动。这是因为在二进制数中,每位的权重是 2 的幂。

以乘以 16 为例,16 等于 2 的 4 次方(2^4 = 16),所以乘以 16 相当于将二进制位向左移动 4 位。然后再按位或,就完成了高低四位的交换,那后续逆向算法再交换一次就回来了,v8[v1++] = v2[strlen(v8)] ^ v3;就是将高低四位交换后的值和输入flag的最后一个元素异或,结果存到V8,那么这部分的逆向算法,就是先将数组的最后一位和第一位异或,然后高低四位交换

for i in range(36):
    auth[36-i-1]^=auth[i]
    #(auth[36-i-1]&0xF0 )>> 4) |((auth[36-i-1]&0xF )<<4)是完成高低四位的交换
    auth[36-i-1]=((auth[36-i-1]&0xF0 )>> 4) |((auth[36-i-1]&0xF )<<4)&0xFF

第二部分,

for ( i = &memStore[18];
        (_QWORD)*(i - 18) * (unsigned __int8)v8[v4] == *(v5 - 3)
     && (_QWORD)*(i - 12) * (unsigned __int8)v8[v4 + 1] == *(v5 - 2)
     && (_QWORD)*(i - 6) * (unsigned __int8)v8[v4 + 2] == *(v5 - 1)
     && (_QWORD)*i * (unsigned __int8)v8[v4 + 3] == *v5
     && (_QWORD)i[6] * (unsigned __int8)v8[v4 + 4] == v5[1]
     && (_QWORD)i[12] * (unsigned __int8)v8[v4 + 5] == v5[2];
        ++i )

从memstore数组,0,6,18位的元素乘以V8的0,1,2要和V5(处理过的auth数组)0,1,2相等,那逆向除一下就行了

for i in range(6):
    for j in range(6):
        auth[6*i+j]=auth[6*i+j]//memostore[j*6+i]

整个代码

auth=[0x0003B148, 0x000D2CAE, 0x0003A1FB, 0x00044F40, 0x000472DE, 0x0000CCC0, 0x00001888, 0x00003B80, 0x000702F7, 0x000C745C, 0x000658E0, 0x000858D4, 0x0000D5BD, 0x00004860, 0x0014F410, 0x0002CB9F, 0x000321DB, 0x0014D534, 0x00025DA0, 0x0006898C, 0x00123D56, 0x00058E4D, 0x00050CF8, 0x00005D64, 0x000978BA, 0x0008F290, 0x0003B568, 0x00054696, 0x00094C12, 0x0001021F, 0x000DBACB, 0x00049680, 0x0002FABD, 0x000F2B58, 0x0012D23C, 0x0014AED3]

memostore=[0x0000000000000D21, 0x000000000000009D, 0x000000000000094B, 0x00000000000003C9, 0x0000000000000C3F, 0x00000000000017E9, 0x000000000000130E, 0x0000000000000088, 0x0000000000000486, 0x000000000000202F, 0x0000000000002230, 0x00000000000024B4, 0x00000000000008B1, 0x0000000000000A9F, 0x0000000000001AD2, 0x00000000000023EB, 0x0000000000000C7E, 0x000000000000042B, 0x00000000000005BF, 0x000000000000113C, 0x0000000000000449, 0x0000000000001751, 0x0000000000000ACE, 0x0000000000001894, 0x000000000000208A, 0x0000000000000E82, 0x00000000000006BD, 0x0000000000000CEE, 0x0000000000002386, 0x00000000000013D4, 0x0000000000000111, 0x0000000000000D1C, 0x000000000000238E, 0x0000000000001759, 0x000000000000012B, 0x000000000000214D]

flag=''

for i in range(6):
    for j in range(6):
        auth[6*i+j]=auth[6*i+j]//memostore[j*6+i]

for i in range(36):
    auth[36-i-1]^=auth[i]
    #(auth[36-i-1]&0xF0 )>> 4) |((auth[36-i-1]&0xF )<<4)是完成高低四位的交换
    auth[36-i-1]=((auth[36-i-1]&0xF0 )>> 4) |((auth[36-i-1]&0xF )<<4)&0xFF




for i in auth:
    flag+=chr(i)
print(flag)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值