170610 逆向-CrackMe之019

本文详细解析了一个名为CrackMe的软件破解过程,通过逆向工程揭示其验证算法,并用Python实现了注册机。针对算法中的难点,如取反运算的不同表现形式进行了深入探讨。

1625-5 王子昂 总结《2017年6月10日》 【连续第251天总结】

A. CrackMe(19)

B. 第19个为Name/Serial类型,拖入PEiD,无壳 C++

那么应该也是mfc界面了

运行,随便输入123以后报出长度不足的提示

暂停查看调用堆栈,锁定MessageBox的调用后就找到主线程了

输入符合要求的Name单步跟下去,在错误提示前不远处有一个call后紧跟着test eax,eax和jnz,NOP掉就爆破成功了

注册机:

处理算法比较明显,虽然有点长但是一个一个看下去就很简单了,按照算法写出注册机即可

004015C7  |> /8B55 E0       /mov edx,[local.8]                       ;  8=循环变量

004015CA  |. |83C2 01       |add edx,0x1                             ;  循环变量+1

004015CD  |. |8955 E0       |mov [local.8],edx

004015D0  |> |8B45 E0        mov eax,[local.8]

004015D3  |. |3B45 E4       |cmp eax,[local.7]                       ;  7=长度

004015D6  |. |7D 42         |jge short Brad_Sob.0040161A

004015D8  |. |8B4D E0       |mov ecx,[local.8]

004015DB  |. |51            |push ecx

004015DC  |. |8D4D EC       |lea ecx,[local.5]

004015DF  |. |E8 1C030000   |call Brad_Sob.00401900

004015E4  |. |0FBED0        |movsx edx,al                            ;  取出第n个字符的ASCII

004015E7  |. |8B45 F0       |mov eax,[local.4]                       ;  与累加和

004015EA  |. |03C2          |add eax,edx                             ;  相加

004015EC  |. |8945 F0       |mov [local.4],eax

004015EF  |. |8B4D E0       |mov ecx,[local.8]

004015F2  |. |C1E1 08       |shl ecx,0x8                             ;  (n-1)左移8位,即乘2的8次方

004015F5  |. |8B55 F0       |mov edx,[local.4]                       ;  与累加和

004015F8  |. |33D1          |xor edx,ecx                             ;  异或

004015FA  |. |8955 F0       |mov [local.4],edx

004015FD  |. |8B45 E0       |mov eax,[local.8]

00401600  |. |83C0 01       |add eax,0x1                             ;  循环变量+1

00401603  |. |8B4D E4       |mov ecx,[local.7]                       ;  长度

00401606  |. |0FAF4D E0     |imul ecx,[local.8]                      ;  长度和(n-1)相乘

0040160A  |. |F7D1          |not ecx                                 ;  取反

0040160C  |. |0FAFC1        |imul eax,ecx                            ;  n*-(n-1)*l

0040160F  |. |8B55 F0       |mov edx,[local.4]

00401612  |. |0FAFD0        |imul edx,eax                            ;  乘以累加和

00401615  |. |8955 F0       |mov [local.4],edx

00401618  |.^\EB AD         \jmp short Brad_Sob.004015C7

0040161A  |>  8B45 F0       mov eax,[local.4]                        ;  累加和初值为0x81276345

但是在python中写注册机的时候有两个问题尝试了很久,直接把取反写上去以后,python中出来的结果明显比内存监视到的大许多,并且有正有负

将每个循环中的值都输出就发现了问题,寄存器是有取值范围的,超过以后会自动舍去高位,而Python不会,因此值要大的许多

解决方法:转换成十六进制字符串后倒着取8位字符,再转换回数值类型

另外,转换为十进制字符串的API是将寄存器的数视作无符号数的,因此没有负号

另外取反在python中只是取负-1,而在寄存器中是以寄存器上限相减得到的

因此这里代码需要用寄存器的位数(2**(4*8))来减,作为取反

这样解决了有正有负的问题


a=input()
l=len(a)
s=2166842181
n=0
while(n<l):
    b=ord(a[n])
    s=s+b
    s=s^(n*256)

    s=s*(~(l*n))*(n+1)
    n=n+1
s=str(hex(s))
if(s[0]=='-'):
    s=2**(4*8)-int(s[-8:],16)
else:
    s=int(s[-8:],16)
print(s)

C.	明日计划
	计算思维

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值