吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2180|回复: 8
收起左侧

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

[复制链接]
xiaoyu2032 发表于 2022-5-3 20:49
本帖最后由 xiaoyu2032 于 2022-5-3 20:57 编辑

160CM-009

  008太简单了,固定明码字符串,直接一看就知道了,因此跳到009。

1.爆破

  先拖到PE中查一下,无壳,VB,请出VB Decompiler,很容易找到函数入口地址以及关键跳转地址(4022CB)。
04.png
  OD中将4022CB行的je改成jnz即可爆破成功。
06.png

2.算法

  根据VB Decompiler反编译出来的VB代码,其中有的VB函数不是很确定的话,百度一下也就搞定了,可以很方便的得出算法的C代码。

 char str1[30];
 int i,m,code;
 double f;
 printf("请输入用户名:");
    scanf_s("%s",str1,30);
 m=0;
 for (i=0;i<=strlen(str1);i++)
 {
  m=m+str1[i];
 }
 printf("m为:%d \n",m);
 code=m*1234567890;
 printf("注册码为:%n \n",code);

  输入用户名abc,发现输出结果为-2109260500。呃。。。好像溢出了,把这个结果输入到程序中,发现失败。取出中间值m(294),用计算器算一下结果是362962959660,输入进去还是失败。
  在OD中F8跟踪了一下程序,发现算法中的中间值m计算是没有问题的,后面好像也是乘1234567890的计算,但是这个函数调用过程好像很奇怪,根据函数的参数变量地址,根本找不到对应的运算结果。
  在VB Decompiler中,去掉“程序分析器和优化器”选项,重新反编译一下,得到的反编译代码如下图所示。
07.png
  其中可以发现和前面的反汇编结果比较,代码可读性更差了,多出来很多看起来没有用处的变量赋值,而且还有两行代码40222F和402254是前面的反汇编代码里面没有的,好像是前一种反汇编方式有问题,漏掉了部分有用的代码。
  本来想用IDA来分析一下算法,结果IDA中没法直接识别到401FF0这个函数,手动创建函数后,按F5,结果显示“Call analysid failed”,百度了半天,也没找到解决办法,只能放弃。
08.png
  重新下载了一个最新的VB Decompiler Pro v11.5,同样反汇编一下,发现和第一次反汇编的结果相比,多出来402254这一行。按这个代码去算一个注册码,发现还是不对。看来还是要到OD里面看看汇编代码,看看到底是怎么回事。
05.png
  进入OD里面F8跟踪运行了一遍,发现有点懵圈(懵了整整一上午……)。以前调试跟踪的时候,汇编的函数调用之前,要么通过寄存器、要么通过指针传值,而这个程序里面,虽然套路也差不多,函数调用前push一堆地址进去,调用完成后有一堆数据更新了,但是查查对应地址的数据,前前后后没有一个对得上。
  比如vbaVarMul函数,百度得到的信息是:

__vbaVarMul ;变体变量相乘

lea eax,var1
push eax ;被乘数
lea ecx,var2
push ecx ;乘数
lea edx,var3
push edx ;结果
call __vbaVarMul ;变量相乘,在eax中返回

  在OD中,对应的代码也类似,而且OD中的右侧的注释中已经自动将var1、var2和SaveTo识别出来了,该函数应该是将var1和var2相乘,结果放入SaveTo位置。但是F8跟踪的时候发现,函数调用前,var1为指针地址12F4AC,指向的变量数值为0x2,var2为指针地址12F434,指向的变量数值为0x3,SaveTo为指针地址12F474,指向的变量数值为0。函数调用后,var1的数值为仍0x2,var2的数值为仍0x3,SaveTo的数值变成了0x5。
  呃……,这哪哪都不对啊。。。
01.png
  在整整懵逼了一上午后,终于找到了一篇介绍VB变量体数据类型的文章,文章地址为https://blog.csdn.net/vbsourcecode/article/details/18662089
  根据介绍,一个VB简单Variant(变量体数据)的表示至少需要12个字节。通常前2个字节是表示类型信息的。从第5个字节到第8个字节并不总是使用到,实际上很少被使用。我们不妨先叫它辅助类型信息。从第9个字节开始就是真正的变量的值了。这里有可能存储一个指针值,也可能是数据,具体是什么取决于变量类型。另一个值得注意的事实是VB的内存是以4个字节对齐的。即使你使用一个字节,那至少也要4个字节来表示。而且编译器只初始化它需要的那些字节,剩余的字节可能是随机数据。
==Variant变量的内部表示==

符号常量 函数值 数值类型
V_Empty 0 Empty(未初始化)
V_Null 1 Null(无有效数据)
V_Integer 2 整数
V_Long 3 长整数
V_Single 4 单精度浮点数
V_Double 5 双精度浮点数
V_Currency 6 货币值
V_Date 7 日期
V_String 8 字符串
V_Object 9 对象
V_Error 10 错误值
V_Boolean 11 布尔值
V_Variant 12 Variant(只与变体中的数组一起使用)
V_Object 13 数据访问对象
V_Byte 17 位值
V_Array 8192 数组

  根据上述内容,实际抓了两个数据案例如下:

地址 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0012F4AC 05 00 00 00 E8 F4 12 00 00 40 77 92 5A 73 65 42

  这表示一个双精度浮点数,1-2字节05表示类型的数值,9-16字节为4265735A92774000,表示浮点数737037030330。3-4和5-8意义不明。

地址 1 2 3 4 5 6 7 8 9 10 11 12
0012F434 03 00 00 00 01 00 00 00 D2 02 96 49

  这表示一个长整型,1-2字节03表示类型的数值,9-12字节为499692D2,表示整型1234567890。3-4和5-8意义不明。
  回头再看一下VB Decompiler去掉“程序分析器和优化器”选项后反汇编的结果,终于明白那些看起来没有任何意义的赋值语句怎么来的了,OD调试也终于可以跟踪到正确的数据了。根据vbaVarMul后面的指令,可以看出是执行了两次vbaMidStmtVar函数,分别将字符串中第4个字符和第9个字符替换成“-”,这样就得到了最终的注册吗。
09.png
  最终得到注册码计算程序如下:

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

int _tmain(int argc, _TCHAR* argv[])
{
 char str1[30],code[30];
 int i,m;
 double f;
 printf("请输入用户名:");
 scanf_s("%s",str1,30);
 m=0;
 for (i=0;i<=strlen(str1);i++)
 {
  m=m+str1[i];
 }
 printf("m为:%d \n",m);
 f=double(m)*double(1234567890);
 sprintf_s(code,"%.0f",f);
 code[3]= 45;       //ASCII "-"
 code[8]= 45;       //ASCII "-"
 printf("注册码为:%s \n",code);
 system("pause");
 return 0;
}

  运行后,输入用户名abc,得到注册码
10.png
  将结果输入程序,注册成功!
03.png

3.总结

  这次破解碰到了一个未接触过的变量体数据类型,在没搞清楚这种数据类型的特点时,完全不知道如何下手。搞清楚以后问题迎刃而解,但是这种数据类型相对来说还是会增加一些跟踪难度(无法直接看到变量数据,需要自己去内存中查找)。

  • 变量体数据类型可以表示各种数据类型,使用变量体函数进行处理时,不需要手动转换数据类型。比如vbaVarMul的运算结果是双精度浮点数,vbaMidStmtVar运算时就自动变成了字符串(整型转字符串)。
  • 逆向时碰到的一些常用的VB函数如下:
函数 功能
rtcMidCharVar 从字符串中取相应字符,对应VB中的MID函数,用法为:MID("字符串","开始的位置","取几个字符")
rtcAnsiValueBstr 取字符的ASCII码数值,对应函数 Asc(string)
vbaLenVar 获得一个字符串的长度,与vbaLenBstr功能类似,只是对应的字符串为变量体数据类型
vbaVarForInit for循环起始,参数为变量体数据类型
vbaVarForNext 循环结构的Next,每次执行时计数加步长,参数为变量体数据类型
vbaStrVarVal 从变量体字符串指定位置上获取字符串(非变量体类型),从str1中取arg开始的字符串,结果返回eax
vbaVarAdd 变量体类型的两数相加,var1+var2,结果返回var3
vbaVarMul 变量体类型的两数相乘,var1 * var2,结果返回var3
vbaVarTstEq 变量体类型的比较,结果返回ax
vbaMidStmtVar 从字符串中取相应字符,与rtcMidCharVar类似,不过操作对象为变量体
vbaVarMove 变量体类型的赋值,将var1赋值给var2
  • 第一次碰到IDA中F5无法生成伪代码的情况,没有找到解决办法。
  • 发现VB Decompiler反编译有时会出现问题,有时候要把“程序分析器和优化器”选项去掉去排查。另外,不同版本的VB Decompiler结果也有不同,比如VB Decompiler V11.5去掉“程序分析器和优化器”选项后反编译的结果如下图,其中存在var_A4先使用再赋值“-”的情况。这个是编译器翻译的问题,就后续机器翻译一样,有时候翻出来的句子比较奇怪的时候,还是需要取查看一下原文(汇编代码)去确认一下准确含义。
    02.png

免费评分

参与人数 6吾爱币 +5 热心值 +5 收起 理由
feiyang1 + 1 + 1 谢谢@Thanks!
Nattevak + 1 + 1 热心回复!
wayyz001 + 1 用心讨论,共获提升!
snakenba580 + 1 + 1 用心讨论,共获提升!
审判者压缩 + 1 + 1 用心讨论,共获提升!
92013 + 1 鼓励转贴优秀软件安全工具和文档!

查看全部评分

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

92013 发表于 2022-5-3 22:28
谢谢分享~~
snakenba580 发表于 2022-5-4 07:21
5853687 发表于 2022-5-4 12:31
SB2500 发表于 2022-5-4 14:00
5853687 发表于 2022-5-4 12:31
谢谢大佬的分享,正在学习中,加油

谢,大佬分享
catprince 发表于 2022-5-4 21:43
学习一下,有时间研究一下
feiyang1 发表于 2022-5-5 02:45
学到了一些新的知识和思路,谢谢楼主
ljdog 发表于 2022-5-5 09:37
不会用,还是有空要学习才行
lmjxf 发表于 2022-5-6 22:11
谢谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-15 23:51

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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