• [CrackMe]160个CrackMe之23


    [CrackMe]160个CrackMe之23

    该题目算法可能不是麻烦,但是由于是汇编编写,循环这里使用栈不容易看出,并且成立条件这里分析时需要拓展下思路,因此花费了一些时间,再次记录一下。

    1. 通过字符串搜索来找到关键位置

      

      直接定位到关键位置,如下图,其是与一个全局变量来进行比较是否为eax。

      现在分析存在两种思路:

      1)直接下内存断点通过OD动态分析;

      2)如果没壳,则可以通过IDA中的交叉索引(x)查看该值在哪里调用。

      

    2. 使用IDA交叉索引功能查看判断位置

      如下图,我们对关键变量进行交叉索引,这里明显存在四处,只要我们把这四处分析完毕,则就能分析出算法来。

      

      1)sub_401023+70 分析

        如下图,我们结合动态与静态分析,发现这是输入用户名,当输入成功之后会+4。

        

      2)sub_40146F+24 分析

        如下图,结合动态与静态分析,是获取Serial

        

      3)sub_40149c+E 分析

        其函数分析如下,我们可以计算出满足serial时需要的值

        

      4)sub_401325+73 分析

        该函数是加密算法,因为其同时出现name和serial的循环运算,这里的循环运算不容易看出,说实话我也不清楚其如何实现循环的(应该通过修改esp)实现的。

        但是通过分析全局变量i,其从0->15时,将add key,4 满足条件,从这里就很容易推断出循环条件。

        另外需要注意一点,其xor并不是单个字符,而是四个字节,(PULONG)&name[i],这也就解释了为什么只循环16次但需要20个字节,否则就会不满足..

        

    3. 加密算法推测与注册机生成

      如下推测出其加密算法

      

      因此我们可以实现注册机编写:

    #include<windows.h>
    #include <iostream>
    
    using namespace std;
    
    
    int main() {
        
        char name[21];
        unsigned long* p;
        memset(name, 0, 21);
        cout << "输入name:" << endl;
        cin >> name;
        unsigned int serial = 0xF6EEDB88;
        
        for (int i = 15; i >=0; i--) {
            p = (unsigned long*)&name[i];
            serial = (serial ^ *p)-1;
        }
    
        cout << serial << endl;
    }

  • 相关阅读:
    线程的几种状态
    NSThread&线程间通信
    大文件下载--断点续传--NSURLConnection
    NSURLConnection及NSURLConnectionDataDelegate
    单例实现 CGD与条件编译实现单例类
    单例模式 饿汉式 ARC
    Load与initialize方法
    单例模式 (懒汉式)ARC
    sqlserver 分页查询总结
    .net 弹窗方式
  • 原文地址:https://www.cnblogs.com/onetrainee/p/12848906.html
Copyright © 2020-2023  润新知