010(算法)

算法

上一节写了暴力破解,这次就来分析一下010是怎么完成注册的,写一个注册机。
还是继续打开注册窗口,在窗口输入一些字符串,打开OD进行
在这里插入图片描述
点击确定之后,看断点,断点停到了关键CALL处,
在这里插入图片描述

关键CALL下面保存了两个立即数
在这里插入图片描述
ECX传参也就是this指针,可以理解为一个函数,然后看一下ECX里面到底是什么,
在这里插入图片描述
右键->反汇编窗口跟随。
在这里插入图片描述
观察一下,发现,注释上有一个ArryData,可以理解为是一个数组,具体数组里保存的什么还得继续观察,然后点击第二个地址,右键->数据窗口跟随
在这里插入图片描述
然后右键,16进制,会发现,这里保存的是用户名,只要可以右键可以数据窗口跟随的,这个地址就可以被访问的
在这里插入图片描述
然后返回到第一个窗口,选择下面的继续,右键->数据窗口跟随
在这里插入图片描述
右键,16进制查看,会发现这里保存的是注册码
在这里插入图片描述
然后F7进入这个CALL,去单步跟踪,

进入CALL以后,观察汇编,把ecx给了edi,ecx是指针,修改一下备注,this->edi,分析完就做一下记录,再回过头来看,会不知道什么是什么
在这里插入图片描述
数据窗口跟随,看ebx里面保存的是用户名,把ebx给了ecx,那么ecx保存的就是用户名。
在这里插入图片描述
用户名下面有三个赋值,也不知道是做什么的,可以略过,没有什么实质性的影响。
在这里插入图片描述
下面有2个CALL,分别跟进去看一下,发现里面的代码有点多,那就先不看,看一下它的返回值,发现这个是判断用户名和密码是否存在的(如果不确定可以不输入尝试一下)
在这里插入图片描述
再往下分析,[ebp-0x24]这是弄了一个局部变量,给了eax。edi这个数据给了eax,保存局部变量
在这里插入图片描述
这里的edi是个数组是根据edi,会发现这个是保存账号密码的数组
在这里插入图片描述在这里插入图片描述
紧接着下面有一个call,进去之后会发现里面有很多的代码,观察一下局部变量,还有寄存器的变化发现,局部变量被填充成注册码
在这里插入图片描述
下面往esi里面保存了一个立即数,数据窗口跟随看了一下,是一个999的字符串,这里也不知道这个是做什么的,先记下来,应该是个全局变量。
在这里插入图片描述
在这里插入图片描述
下面这个call也没做什么事情,继续分析。
下面esi+4,跟过去看一下,发现又是一个字符串,继续往下分析
在这里插入图片描述
继续往下走,数据窗口跟随一下,发现是当时出入的注册码,
在这里插入图片描述
对比一下输入的字符串,是第四个字节,放倒数组里,应该是第三个字节,下面那个也是一样的,
在这里插入图片描述
下面有一个判断,判断是否等于9c,
在这里插入图片描述
不满足条件就会跳转,跟过去看一下,发现还是判断是否等于FC
在这里插入图片描述
不满足条件,继续跳转,判断是否等于AC,不等于AC就退出了!
在这里插入图片描述
由此可知道,BL=password[5]= 9c ac fc,
继续分析下面的代码,一步步分析即可,写上注释
在这里插入图片描述
下面有一个call,跟进去看一下
在这里插入图片描述
然后继续一步一步分析
在这里插入图片描述
进入call 发现代码不是很长,一步一步分析一下
在这里插入图片描述
在往下继续分析,下面还有一个call进去之后发现代码还不是很长,继续跟一下
在这里插入图片描述
往下看,有好几个判断,依次看一下,
在这里插入图片描述
分析到这里,稍微停止一下,下面还是判断,写一个小的程序,让它满足上面所写的需求,满足后要求后,后面好继续分析。

// 注册机.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
#include <time.h>


int _tmain(int argc, _TCHAR* argv[])
{
	srand(time(NULL));
	byte k[10] = { 0x11, 0x22, 0x33, 0x9c, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00 };

	while (true)
	{
		byte k0=rand()%0xff;
		byte k6 = rand()%0xff;

		byte al = (k0 ^ k6 ^ 0x18 + 0x3D) ^ 0xA7;
		if (al >0)
		{
			k[0] = k0;
			k[6] = k6;
			break;
		}
	}
	
	while (true)
	{
		byte k1 = rand() % 0xff;
		byte k7 = rand() % 0xff;
		byte k2 = rand() % 0xff;
		byte k5 = rand() % 0xff;

		DWORD ESI = (0x100 * (k1 ^ k7 & 0xff) + k2 ^ k5 & 0xff) & 0xffff;
		DWORD eax = (((ESI ^ 0x7892) + 0x4d30) ^ 0x3421) & 0xffff;

		if (eax % 0xb == 0 && eax / 0xb <= 0x3e8)
		{
			k[1] = k1;
			k[2] = k2;
			k[7] = k7;
			k[5] = k5;
			break;
		}
	}
	printf("%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X", k[0], k[1], k[2], k[3], k[4], k[5], k[6], k[7], k[8], k[9]);
	
	getchar();
	return 0;
}


剩下就是用户名与密码对应关系了,不往上发表了。

猜你喜欢

转载自blog.csdn.net/dohxxx/article/details/85331746