吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2348|回复: 15
收起左侧

[原创] 练习笔记之160Crackme-011

  [复制链接]
xiaoyu2032 发表于 2022-5-7 12:45
本帖最后由 xiaoyu2032 于 2022-5-7 12:48 编辑

160CM-011

1.破解过程

  先看看题,打开运行,界面如下图所示,要求输入正确的序列号,然后状态会成未注册变成已注册。序列号不正确时没有提示。
02.png
  先拖到PE看看,无壳,VB,那VB Decompiler先来一波。
04.png
  从左侧的函数列表可以看出,有一堆是事件响应函数,分别对应界面上的按键,另外还有4个定时处理函数。简单的浏览一下可以发现,注册算法应该在定时处理函数里面,按键处理函数只负责对按键进行响应和显示。
  这道题爆破太简单了,就不说了,主要分析一下算法。4个定时处理函数里面的内容基本相同,每个里面都是好几个重复的验证算法,取其中一个进行分析。

  For var_24 = 1 To Len(var_44) Step 1
  loc_0040492F: 
  If var_F8 = 0 Then GoTo loc_00404A60
  var_50 = CStr(Left(var_44, 1))        '取字符串的第一个字符
  var_304 = Asc(Mid$(CStr(var_44), CLng(var_24), 1))    '依次取字符串中的第n个字符,并转换成ASCII码值
  var_8C = Hex$((var_30C + var_CC))     '上面的ASCII码值+var_CC后转成16进制字符串
  var_34 = var_34 & Hex$((var_30C + var_CC))        '16进制字符串加在字符串的后面
  Next var_24
  GoTo loc_0040492F

  上面代码理解起来不难,需要注意的是var_304和var_30C其实是同一个变量(一个是变量体的指针地址,一个是变量体中存储数据的指针地址),然后有个var_CC不知道是什么东西,VB Decompiler去掉“程序分析器和优化器”重新编译也查不出这个变量的来源,只好到OD里面跟跟看了。
06.png
  OD加载程序,然后运行,输入“12345#”后,再找到函数入口地址404650,然后往下找到第一个段算法中for循环的起始位置和结束位置,在起始位置前一行和结束位置后一行设下断点。第一个断点断下后,F8单步跟踪一下,可以发现算法在取完第一个字符后,进行了一些浮点运算,然后就得到一个数字和ASCII码值相加了。
05.png
  浮点运算的汇编指令看不董,只好百度一下,备注好,基本可以看出是将取出的字符串转换成浮点数后与ASCII码值相加,也就是说var_CC就是取出字符串的浮点数值。
  跟完一遍for循环后再点运行,然后断在第二个断点(404A60)位置,我们查看一下ebp-0x34对应的地址(12FB44)的数据,根据变量体数据类型的结构,08表示字符串,“0015F2D4”为字符串的地址。
07.png
  查看一下“0015F2D4”地址的字符串内容,字符串为“032333435362B24”,除第一个0外,其余和字符串“12345
#”的ASCII码加“1”均吻合。
08.png
  再回去F8跟踪一下前面的代码,发现在4048CF位置对整型变量体var_34赋值为0,然后在404A01字符串连接时,var_34变成了字符串变量体,数值0自动转成成字符串“0”,放在了最前面。VB Decompiler对这部份的识别还是有些问题的。
09.png
  至此,核心的算法过程已经弄清楚了。可是程序里面为什么要整4个Timer?每个Timer里面还反复的进行计算,然后和一串字符进行比较。仔细看了看算法,发现不同的算法中中,唯一的区别就是“CStr(Left(var_44, 1))”这一行了,有的是取1个字符,有的是取2个、3个……
  但是除了这个区别,还是反反复复在重复啊,嗯,好奇怪。
  我们在看看算完以后要比较的字符串,“0817E747D7AFF7C7F82836D74RR7A7F7E7B7C7D826D81KE7B7C”。呃……不是16进制字符串吗?怎么字母“R”、“K”也有,那怎么可能相等呢?
  其实这些都是程序作者(机智的作者)的障眼法,看起来一大堆的字符串长的都一样,其实仔细比较一下可以发现有些串串还是不一样的。由于前面算法过程分析已经很明确了,计算后的字符串是16进制字符串,因此我们需要找一串不包含16进制字符以外的串串。最终只有Timer1中有一个串串符合要求。

  For var_24 = 1 To Len(var_44) Step 1
  loc_004064A8: 
  If var_24 = 0 Then GoTo loc_004065D9
  var_50 = CStr(Left(var_44, 2))
  var_3A0 = Asc(Mid$(CStr(var_44), CLng(var_24), 1))
  var_8C = Hex$((var_3A8 + var_CC))
  var_34 = 0 & Hex$((var_3A8 + var_CC))
  Next var_24
  GoTo loc_004064A8
  loc_004065D9: 
  If (var_34 = "0817E747D7A7D7C7F82836D74747A7F7E7B7C7D826D817E7B7C") = 0 Then GoTo loc_0040664F
  Set var_54 = Me
  Label3.Caption = "REGISTRIERT"
  var_eax = %fobj
  loc_0040664F: 

  从这个代码中可以发现,字符的ASCII码需要加的是字符串前两位。由于ASCII码是个两位16进制数,两位10进制数换成16进制数也最多只有两位,而两个两位16进制数相加,其和即时是三位16进制数,其最高位也不可能超过1。因此这一长串字符串,去掉第一个“0”后,应该是每两个字符表示一个序列号数字。假设序列号第一个数字为a1,第二个数字为a2,则可以列出两个等式:
129(81的10进制表述)=a1的ASSII码+a110+a2;
126(7E的10进制表述)=a2的ASSII码+a1
10+a2;
  从上面的计算式可以看出,数字a1的ASCII码值比数字a2的ASCII码值大3,也就是说数字a1比数字a2大3,因此数字a1最小也应该是3,此时数字a2应该为0。3个ASCCII码为51(10进制),0的ASCII码为48(10进制),代入第一行,a1的ASSII码+a110+a2=51+30+0=81,与129相比还小48。假设正确的a1需要比3大n,则n+10n+n=48,求解得到n=4。因此a1=3+4=7,a2=0+4=4。
  这样我们就可以将长串反向解析出来,公式为
字符串中取出的两个字符转换成10进制数-78,即为输入数字的ASCII码值。
  编写注册码计算程序如下:

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
    char key[100] = "817E747D7A7D7C7F82836D74747A7F7E7B7C7D826D817E7B7C";
    char code[100] = "";
    char a[10]="",b[10]="";
    int i,j,m,n;
    for (i=0;i<(strlen(key)/2);i++)
    {
        sprintf_s(a,"%c",key[i*2]);
        sprintf_s(b,"%c",key[i*2+1]);
        //printf("a=%s \n",a);
        //printf("b=%s \n",b);
        m=strtol(a,NULL,16);
        n=strtol(b,NULL,16);
        j=m*16+n-74;
        //printf("j=:%d \n",j);
        code[i]=j;
    }
    printf("注册码为:%s \n",code);
    system("pause");
    return 0;
}

  输入计算得到的注册码,成功结果如下:
01.png

2.总结

  • 再一次证明,VB Decompiler虽然好用,但也不可全信,有问题的地方还是得看汇编代码。
  • 碰到一些浮点运算的指令,都不认识,这里整理一下。
指令 说明
fld 将浮点数据压入协处理器的堆栈中
fild 将整型数据压入协处理器的堆栈中
fst 将协处理器堆栈栈顶的数据传送到目标操作数中
fstp 与FST相类似,所不同的是:指令FST执行完后,不进行堆栈的弹出操作,即:堆栈不发生变化,而指令FSTP执行完后,则需要进行堆栈的弹出操作,堆栈将发生变化
fstsw 取协处理器的状态字
fadd 浮点数相加
fclex 浮点检查错误清除
  • 野生菜鸟选手的悲哀,C语言的字符串函数都要现搜现用,怎么依次取字符串中的两个字符都尝试了各种方法之后才解决,怎么将16进制数字转换成16进制字符串又是各种折腾,动不动就是:==不能将参数 1 从“char”转换为“const char *”==
  • VB逆向碰到的一些新函数:
函数 功能
rtcR8ValFromBstr 将var1(字符串)转换成双精度浮点数存入ST0
vbaI4Var 将一个var1(变量体)转换为I4(长整数),结果存入eax
rtcHexBstrFromVar 将var1(变量体)转换为16进制字符串,结果存入eax
vbaVarCat 将var2(变量体)连接到var1(变量体)的后面,结果存入var3(变量体)中
03.png

免费评分

参与人数 7吾爱币 +6 热心值 +7 收起 理由
zy870527 + 1 + 1 谢谢@Thanks!
SANJINHERE + 1 + 1 我很赞同!
stellarMC + 1 + 1 热心回复!
RANY2021 + 1 + 1 我很赞同!
审判者压缩 + 1 + 1 用心讨论,共获提升!
szjszj + 1 + 1 我很赞同!
tfrist + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

tfrist 发表于 2022-5-7 13:29
分析的不错不错 VB的程序
hackerbob 发表于 2022-5-7 13:51
ehcapa 发表于 2022-5-7 14:23
lgslegend 发表于 2022-5-7 15:28
&#128077;&#128077;
dinds 发表于 2022-5-7 16:27
学习了。。谢谢
snakenba580 发表于 2022-5-7 18:03
谢谢分享,正在学习中。
戰龍在野 发表于 2022-5-7 19:25
谢谢你的坚持我也来好好学习了
JohnWAPJ 发表于 2022-5-8 01:22
好厉害啊
stellarMC 发表于 2022-5-8 11:21
厉害了,学习了,感谢分享,11点21分2022年5月8日!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-25 02:13

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表