转载请注明出处。https://rhirufxmbcyj.gitlab.io
从看雪一篇帖子上看到的这个程序,没什么难度,就是比较绕。拿下来试一试。
程序:https://rhirufxmbcyj.gitlab.io/files/give_a_try.rar
准备工作
- 首先,打开程序看一看这是个什么类型的程序,是个name+password类型还是serial类型,心理也好有个底,这个程序只有一个编辑框,也就是个serial类型的。
- 然后使用PEiD等工具 进行查壳、查语言、查算法。
- 有壳先脱壳,尽量不干扰正常分析程序,能用工具脱就用工具脱,此程序无壳。
- C类语言大多都一样,不需要特殊的工具,像Delphi或VB或Net就需要使用特定的工具去分析了,这个程序是汇编写的,更容易分析,怪不得函数那么少。
- 使用PEid的插件Krypto ANALyzer查一下算法,也算是分析的时候考虑算法有个偏向。
分析
程序拖入IDA看一看,发现未知的函数只有几个,其他都是API,直接用IDA的f5一个函数一个函数看就找到了程序的校验算法那块,也就是sub_401103(char *a1),猜测参数1这个char *就是输入的字符串了。
这个是IDA的关键算法的伪代码。
int __stdcall sub_401103(char *a1)
{
int result; // eax@2
int v2; // edi@3
char v3; // al@3
char *v4; // esi@3
unsigned int i; // ebx@6
unsigned int v6; // eax@7
unsigned int v7; // edx@7
unsigned int v8; // edx@7
unsigned int v9; // edx@7
unsigned int v10; // edx@7
unsigned int v11; // edx@7
unsigned int v12; // edx@7
unsigned int v13; // edx@7
unsigned int v14; // edx@7
unsigned int v15; // edx@7
unsigned int v16; // edx@7
unsigned int v17; // edx@7
unsigned int v18; // edx@7
unsigned int v19; // edx@7
unsigned int v20; // edx@7
unsigned int v21; // edx@7
if ( strlen(a1) == 42 ) // 字符串长度必须42
{
v2 = 0;
v3 = *a1;
v4 = a1 + 1;
while ( v3 ) // 将每个字符串的ascii累加到V2里
{
v2 += (unsigned __int8)v3;
v3 = *v4++;
}
srand(dword_40406C ^ v2); // 没有用time(NULL)取随机数,也就是这个随机数是可以追朔的,所以这里是个突破口,前提是dword_40406c要确定
for ( i = 0; i != 42; ++i )
{
v6 = (unsigned __int8)a1[i] * rand();
v7 = v6 * (unsigned __int64)v6 % 0xFAC96621;
v8 = v7 * (unsigned __int64)v7