原始出处:来自 <https://bbs.pediy.com/thread-100167.htm>
[ 破文标题 ] 对抗某反调试CM
[ 破解工具 ] OD、IDA
[ 破解平台 ] Windows 7
[ 软件名称 ] KGM1Tal.exe
[ 软件大小 ] 4.00 KB
[ 软件下载 ] CM.rar
[ 保护方式 ] 无壳
[ 软件简介 ] 老外写的CM
[ 破解声明 ] 纯属兴趣,无其它目的,如有错误,望指出!
[ 破解过程 ]-------------------------------------------------------------------------------------
1、测试软件随便乱输入提示Try Again,something did not work right
2、直接拖进IDA查找关键字符串或则静态分析代码
2、1:sub_401519函数(检测401296处代码有没有被下CC断点)
2、2:sub_4014A9函数(检测GetDlgItemTextA首几个字节CC断点)
2、3:关键代码处sub_401296函数
2、4:sub_401332函数分析
1、第一个判断密码取值范围必须在0x41~0x5A之间(A~Z)
2、将用户名数据累加结果除以0x18将余数保存到0040304F里面
3、判断密码第二位是不是 == 0x45(E),并且检测CC断点
出来后还是检测CC断点的
总结函数功能:
1、判断密码的合法性
2、将用户名累加起来的结果/0x18,将余数保存到0040304F里面
3、检测0x401420、0x401296的CC断点
3、分析核心算法部分sub_4013B6
原始出处:来自 <https://bbs.pediy.com/thread-100167.htm>
[ 破文标题 ] 对抗某反调试CM
[ 破解工具 ] OD、IDA
[ 破解平台 ] Windows 7
[ 软件名称 ] KGM1Tal.exe
[ 软件大小 ] 4.00 KB
[ 软件下载 ] CM.rar
[ 保护方式 ] 无壳
[ 软件简介 ] 老外写的CM
[ 破解声明 ] 纯属兴趣,无其它目的,如有错误,望指出!
[ 破解过程 ]-------------------------------------------------------------------------------------
1、测试软件随便乱输入提示Try Again,something did not work right
2、直接拖进IDA查找关键字符串或则静态分析代码
2、1:sub_401519函数(检测401296处代码有没有被下CC断点)
2、2:sub_4014A9函数(检测GetDlgItemTextA首几个字节CC断点)
2、3:关键代码处sub_401296函数
2、4:sub_401332函数分析
1、第一个判断密码取值范围必须在0x41~0x5A之间(A~Z)
2、将用户名数据累加结果除以0x18将余数保存到0040304F里面
3、判断密码第二位是不是 == 0x45(E),并且检测CC断点
出来后还是检测CC断点的
总结函数功能:
1、判断密码的合法性
2、将用户名累加起来的结果/0x18,将余数保存到0040304F里面
3、检测0x401420、0x401296的CC断点
3、分析核心算法部分sub_4013B6
提取算法:
/*
时间:10点38分
功能:
分析某CM的注册算法
*/
#include "stdafx.h"
#include <windows.h>
#include "defs.h" //IDA宏文件来的
//为了省事定义成全局变量了
char InputName[] = { "24214214213" }; //省事直接写死了
char InputPassword[0xA] = { 0 }; //密码长度必须是10
byte Remainder = 0; //保存余数的
DWORD dword_40304A = 0; //保存密码的余数
byte byte_40304E = 0; //备份
char __stdcall sub_4013B6(char* a1)
{
unsigned int v1=0; // eax@1
signed int v2=0; // ebx@1
int v3=0; // ecx@1
int v4=0; // eax@4
int v5=0; // eax@6
unsigned int v6=0; // ecx@8
char v7=0; // dh@8
LOBYTE(v4) = Remainder;
if (Remainder > 0x18)
{
LOBYTE(v4) = Remainder - 0x18;
}
byte_40304E = v4;
InputPassword[0] = a1[byte_40304E];
v4 = (unsigned __int8)v4;
LOBYTE(v5) = Remainder + v4;
if ((unsigned __int8)v5 > 0x18u)
LOBYTE(v5) = v5 - 0x18;
v6 = 2;
InputPassword[v6] = a1[v5];
v7 = InputPassword[v6];
while (v6 < 8)
{
byte_40304E = v5;
v5 = (unsigned __int8)v5;
++v6;
LOBYTE(v5) = v7 - 0x41 + v5;
if ((unsigned __int8)v5 > 0x18u)
{
LOBYTE(v5) = v5 - 0x18;
}
InputPassword[v6]=a1[v5];
v7 = InputPassword[v6];
}
unsigned int AddSum = 0; //保存累加的结果
for(int i=0;i<9;i++)
{
AddSum += InputPassword[i];
}
AddSum = AddSum / 0x9;
InputPassword[9] = AddSum;
return 0;
}
int main()
{
//1、先将InputName数据循环累加的结果/0x18,并将余数保存起来
byte AddSum = 0; //保存累加的结果
int i = 0;
while (InputName[i] != 0)
{
AddSum += InputName[i];
i++;
}
Remainder = AddSum % 0x18;
InputPassword[1] = 'E'; //第二位必须是E
char aZwatrqlcghpsxy[] = {"ZWATRQLCGHPSXYENVBJDFKMU"};
sub_4013B6(aZwatrqlcghpsxy);
return 0;
}