Crackme024

Crackme024 的逆向分析 

1.程序观察

 

程序界面和023一样。

2.简单查壳

 使用汇编语言编写,无壳。

3.程序分析

使用 OD 载入程序,搜索字符串。

可以看到,程序的关键代码就在上方不远处

 

 

代码虽少,但是干的活却不少。总共分为以下四步:
  1.得到输入
  当输入事件发生的时候,首先程序得到输入的序列号,判断是否为空。然后得到输入的用户名,也判断是否为空。如果都不为空,继续验证;如果任意一个为空,就跳转走。
  2.计算key值
  接着程序有一个循环,循环次数为 0x10 次。程序使用我们输入的用户名计算得到一个 key。
  3.修改代码
  将计算得到的 key 和输入的 serial 相加,得到新的 key。然后使用内存 4012D9 处的值依次和key进行异或运算和减法运算。目的是修改内存 4012D9 处的代码。
  4.验证
  验证程序是一个长度为 0x3E 的循环。程序从地址 4011EC 开始,每次取四字节进行异或运算。最后计算出来的值和 0xAFFCCFFB 作比较。如果相等,跳转到地址4012D9处。

如果我们输入的序列号是正确的话,那么地址4012D9处的代码应该是跳转到地址401301。如果我们的输入不正确,那么无论如何也是跳转不到正确的提示处的。

接下里该我们可以倒推出地址4012D9处正确的代码:
因为我们知道输入:0,也知道输出:0xADDCCFFB,也知道计算过程:循环进行异或运算,那么应该可以计算得出地址4012D9处的值。

因为只有地址4012D8和地址4012DC这总共8个字节的值是不确定的,其余的值都是固定的。这两个地址处的值分别为 xxxxxx04 和 D833ADxx(xx表示未知的值)。

也就是说 23E989A7 xor xxxxxx04 xor D833ADxx = AFFCCFFB,所以 xxxxxx04 xor D833ADxx = 8C15465C。可以计算出这两个值分别为 5426EB04 和 D833AD58。

所以从4012D9处的四字节值为 585426EB

然后可以倒推出 key 的值:

00584554 xor newkey = 5854xxxx
xxxx - newkey>>0x10 = 26EB
 
第一个式子可以算出,newkey 的前4位为 580c。第二个式子可以算出 xxxx 为 7EF7。所以 00584554 xor 580cxxxx = 58547EF7,可以算出 newkey一定为580C3BA3。

由于 newkey = oldkey + serial。

而 oldkey 是由用户名计算得到,所以我们可以很简单的写出注册机。

4.注册机

#include <stdio.h>
#include <string.h>
#include <Windows.h>

int Keygen()
{
    unsigned long key = 0x58455443;
    char szName[20] = { 0 };
    unsigned long* p;

    printf("请输入用户名:");
    scanf_s("%s", szName, 20);

    for (int i = 0; i <= 15; i++)
    {
        p = (unsigned long*)& szName[i];
        key += *p;
        
    }
    unsigned long serial = 0x580C3BA3 - key;
    printf("%u", serial);

    return 0;
}

int main(int argc, char* argv[])
{
    Keygen();
    return 0;
}

 

相关文件在我的 Github:https://github.com/UnreachableLove/160-Crackme/upload/master/Crackme024

原文地址:https://www.cnblogs.com/white-album2/p/11670744.html