新160个CrackMe045-CyTom-crackme、046-keyme1、047-surre逆向分析

045

无壳

暴力破解

根据字符串查找到相关跳转,直接将其改成jmp即可获取破解版本

算法分析

想上找到函数头下断点,重新分析程序先是获取用户名和序列号,之后再将序列号字符串转换成整数,接下来将用户名字的字符ASCII码累乘取后28位,将得到的结果与转换成整数的序列号进行对比相等则成功,不相等则失败

在撰写解码器时需要注意每一次累乘结果都需要取后32位,因为寄存器只能存32位,在这里的算法中也没有对溢出进行特殊处理,因此可以写出keygen:

python 复制代码
username=input("Input username:").strip()



serial=1

for ch in username:

    serial=serial*ord(ch)& 0xFFFFFFFF



serial=serial&0xFFFFFFF

print(f"serial{serial}")

046

UPX壳

去壳

暴力破解

字符串查找到关键跳转,将其给nop掉即可获得破解版本

算法分析

向上找到函数头,重新分析,发现在输入序列号之前就会进行一个数字预处理,之后将处理好的数据存储到444410处为30314010,之后再将输入的序列号与存储的数据30314010判断是否相等,如果相等则弹出成功语句

向上分析可以找到相关算法分别对内存的三个位置的数据进行了操作,地址分别为4445558、4445554、444555C,方便描述分别给他们起名为a1,a2,a3可以根据这个算法分析出伪代码为:a3*0xCDD+a1*a2+a3-a1+a3。在内存处查看相关地址内存储的数据可以找到a1=0x02,a2=0x06,a3=0x23F0

关于这个数据是怎么计算出来的,在401390函数中生成a1,a2,a3值,从函数中可以发现是从系统的版本号中直接获取的,因为程序是比较旧的程序,系统兼容性等问题,所以pyhton代码中没办法获取到程序计算使用的版本号,这里直接使用版本号

可以生成keygen为:

python 复制代码
a1=0x02

a2=0x06

a3=0x23F0



print(a3*0xCDD+a1*a2+a3-a1+a3)

047

无壳

在x32dbg中没有找到相关线索,但是可以在IDA中发现函数名没有被魔改,还可以找到关键函数以及他所对应的地址429D24

暴力破解

根据找到的函数向下继续可以找到一个关键跳转,将他给nop掉即可获取破解版软件

算法分析

对文件中的字符串进行ASCII码值的累加,累加之后将和与0x20A9进行对比,相等则成功,不相等就失败

可打印字符中ASCII码值最大为126,也就意味着文件中至少有67个字符,使用随机生成算法每次随机生成一个数之后用目标值-随机ASCII码值,直到差也在可打印范围内,可以生成keygen:

python 复制代码
import random



def generate_string(target=0x20A9):

    MIN, MAX = 32, 126

    chars = []

    

    while target > MAX:

        # 随机生成字符,但要保证剩余的能达到

        max_val = min(MAX, target - MIN)

        min_val = max(MIN, target - MAX)

        if min_val > max_val:

            min_val, max_val = MIN, MAX

        val = random.randint(min_val, max_val)

        chars.append(val)

        target -= val

    

    chars.append(target)

    return ''.join(chr(c) for c in chars), chars



# 测试

for _ in range(3):

    s, vals = generate_string(0x20A9)

    print(f"\n字符串: {s}")

    print(f"长度: {len(s)}")

    print(f"累加和: {sum(vals)} (0x{sum(vals):04X}) ✓")