前言
2021年DASCTF三月赛逆向部分的学习,这个题又是一道程序运行时修改了特定函数的保护属性,从而在函数内部写入了其他函数的内存地址,达到跳转的目的,之前好像遇到过类似的题目,但这个题目一开始仍然没有分析出来,后面看了其他师傅的WP后有了思路,从头到尾独立完成了下,在此做一记录。
一、题目分析
题目上来一看,貌似逻辑挺简单:
貌似很简单,然后bytes.fromhex,异或回去,得到了一个
很好假flag,意料之中,怎么可能这么简单,然后就不会了,之后学习了一下,关键地方还是在:
这里1这部分是获取了IsDebuggerPresent函数的内存地址,后面又通过2,3改变了IsDebuggerPresent_0的内容,通过动态调试看到里面究竟是什么:
跟进IsDebuggerPresent后发现,函数直接跳转到4015c3这个位置,就可以看到真正的加密函数了,所以真正写入byte_4080E0的内容是这里的,之前写入的被覆盖掉了,这里还需要注意的是这个函数几个地方插入了花指令,一开始是无法生成伪代码的,需要去花,花指令就在两条条件跳转jnz jz 以及后面的机器码E8,干扰后面的反汇编,之际把这些地方都nop掉,重新定义函数,就可以看到如下内容:
这里加密的逻辑就是经过五次盲盒打乱,然后每隔6个读一个,相当于栅栏,栅栏深度为6,其次就是里面有数据格式干扰我们,一会儿DWORD,一会儿unsigned int8,一会儿又是bytes,其实没什么影响,存在内存中都一样,可以当成从头到尾都是字符串就行了
二、代码示例
# -*- coding: utf-8 -*-
"""
Created on Thu Jun 30 21:00:30 2022
@author: 荣的男人
"""
import libnum
#key = [39,3,10,118,30,26,54,46,73,46,48,28,118,28,95,99,86,40,19,105,116,95,31,85]
v1 = 0x416f6b116549435c2c0f1143174339023d4d4c0f183e7828
enc = libnum.n2s(v1)
enc = list(enc)
print(enc)
enc1 = []
for x1 in range(4):
for x2 in range(6):
enc1.append(enc[4 * x2 + x1])
print(enc1)
a = [ 0x80, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x2F, 0x00,
0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
0x37, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x40, 0x00,
0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
0x4B, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x55, 0x00,
0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x00,
0x17, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00