2、Afkayas

002---Afkayas.1

简述:

难度:一颗星

保护方式:||Name/Serial(VB5)

操作系统: Windows(95)[I386, 32 位, GUI]

编译器: Microsoft Visual Basic(5.0)

语言: VB

界面

双击打开后是这样的。

直接随便输入一个错误的。

这时候就可以直接拖入x32dbg了

初探

在x32dbg和之前的思路一致,直接跑起来,弹窗后直接使用堆栈回调的方式即可

有以下的汇编,比较有意思 这个如果没有猜错的话,应该就是这个了。首先暴力破解一下

0040258 | 68 801B4000       | push afkayas.1.401B80                  | 401B80:L"You Get It"
0040259 | 68 9C1B4000       | push afkayas.1.401B9C                  | 401B9C:L"\r\n"
0040259 | FFD7              | call edi                               |
0040259 | 8BD0              | mov edx,eax                            |
0040259 | 8D4D E8           | lea ecx,dword ptr ss:[ebp-18]          |
0040259 | FFD3              | call ebx                               |
004025A | 50                | push eax                               |
004025A | 68 A81B4000       | push afkayas.1.401BA8                  | 401BA8:L"KeyGen It Now"

在他的上一句je打一个断点

0040258 | 74 58             | je afkayas.1.4025E5                    |
004025E | 52                | push edx                               |
004025E | EB 56             | jmp afkayas.1.40263B                   |

------------------------------------------------------------------------------
004025E | 68 C81B4000       | push afkayas.1.401BC8                  | 401BC8:L"You Get Wrong"
004025E | 68 9C1B4000       | push afkayas.1.401B9C                  | 401B9C:L"\r\n"
004025E | FFD7              | call edi                               |
004025F | 8BD0              | mov edx,eax                            |
004025F | 8D4D E8           | lea ecx,dword ptr ss:[ebp-18]          |
004025F | FFD3              | call ebx                               |
004025F | 50                | push eax                               |
004025F | 68 E81B4000       | push afkayas.1.401BE8                  | 401BE8:L"Try Again"

跳转到了横线的下方,我直接将其nop掉就可以实现破解了。但是我们要分析其算法,所以这样是不行的。

所以我们网上看跳转

0040257 | 66:85F6      | test si,si                                     |
0040257 | 8945 94      | mov dword ptr ss:[ebp-6C],eax                  |
0040257 | 894D AC      | mov dword ptr ss:[ebp-54],ecx                  |
0040258 | 8945 A4      | mov dword ptr ss:[ebp-5C],eax                  |
0040258 | 894D BC      | mov dword ptr ss:[ebp-44],ecx                  |
0040258 | 8945 B4      | mov dword ptr ss:[ebp-4C],eax                  |
0040258 | 74 58        | je afkayas.1.4025E5                            |

发现有一个je 上面影响 zf标志位的只有test位置,test指令的意思 两个操作数按位与,这里就是判断si是否等于0

继续往上翻,看看si的值是怎么来的。

0040253 | FF15 2841400 | call dword ptr ds:[<&__vbaStrCmp>]             |
0040253 | 8BF0         | mov esi,eax                                    |
0040253 | 8D55 E0      | lea edx,dword ptr ss:[ebp-20]                  |
0040253 | F7DE         | neg esi                                        |
0040254 | 8D45 E8      | lea eax,dword ptr ss:[ebp-18]                  |
0040254 | 52           | push edx                                       |
0040254 | 1BF6         | sbb esi,esi                                    |
0040254 | 8D4D E4      | lea ecx,dword ptr ss:[ebp-1C]                  |
0040254 | 50           | push eax                                       |
0040254 | 46           | inc esi                                        |

才在这个call位置打个断点,因为我们不熟悉vb语言,所以我们采用多次调试的策略。来进行猜测其功能。cmp反正是与比较有关的。

堆栈的值
0019F040   004656EC     L"AKA-1658111"
0019F048   08C92D64     L"Type In Your Serial"

其实这里就可以看出来了,如果相等就是0不相等就是1 或者 -1 盲猜一下

开始还原

发现是这样的。于是我们重新跑一下,看看正确的结果是什么。

用户名不变,直接改密码,我这里测试了一下, 我使用eax AKA-1658111 的时候,返回值为0

那我们再来个比这个字符串ASCII小的。

0019EF88   09D640A4     L"AKA-1658111"
0019EF8C   0045701C     L"AAAAA"

发现eax为 FFFFFFFF

其实这里不管1或者-1最后都变成了0。等下我们要分析一下他的这一步的算法,先把这个还原看看。

到这里可以看出来。当用户名为:Type In Your Name​ 的时候。秘钥为"AKA-1658111"

以往的经验可以知道。- 的左右两边是分开的。所以……先看看AKA咋生成的。

0040251 | 68 701B400 | push afkayas.1.401B70                             | 401B70:L"AKA-"

其实这里就可以看出来了,AKA- 是本来就在内存中的。也就是说不需要我们还原,就是写死的。

所以我们就要开始分析1658111 是如何生成的了。开始逆向还原了。首先我们可以猜到肯定是由用户名进行生成的。

翻到开始的位置

0040241 | 50         | push eax                                         | eax:L"Type In Your Name"
0040241 | 8B1A       | mov ebx,dword ptr ds:[edx]                       |
0040241 | FF15 E4404 | call dword ptr ds:[<&__vbaLenBstr>]              |
0040241 | 8BF8       | mov edi,eax                                      | 求字符串的长度
0040241 | 8B4D E8    | mov ecx,dword ptr ss:[ebp-18]                    | [ebp-18]:L"Type In Your Name"
0040242 | 69FF FB7C0 | imul edi,edi,17CFB                               |

发现有这个字符,

可以猜到。这个还原是

strlen("Type In Your Name") * 0x17CFB

下一步有一个jo。如果溢出则直接报错了就。无需管他。

继续向下分析

0040242 | 0F80 91020 | jo afkayas.1.4026BE                              |
0040242 | FF15 F8404 | call dword ptr ds:[<&rtcAnsiValueBstr>]          |
0040243 | 0FBFD0     | movsx edx,ax                                     | edx:L"ype In Your Name"
0040243 | 03FA       | add edi,edx                                      | edx:L"ype In Your Name"

这个函数也是使用多执行几次,猜测他的作用,这里是直接去取出第一个字符。

然后加上edi的结果。

0040243 | 0F80 80020 | jo afkayas.1.4026BE                              |
0040243 | 57         | push edi                                         |
0040243 | FF15 E0404 | call dword ptr ds:[<&__vbaStrI4>]                | 十六进制转十进制
0040244 | 8BD0       | mov edx,eax                                      |
0040244 | 8D4D E0    | lea ecx,dword ptr ss:[ebp-20]                    |

最后这个呢。就是直接将16进制转换成十进制的字符串,这里转换完成后就已经拿到了结果了。

0040243 | FF15 E0404 | call dword ptr ds:[<&__vbaStrI4>]                | 十六进制转十进制
0040244 | 8BD0       | mov edx,eax                                      | edx:L"1658111", eax:L"1658111"
0040244 | 8D4D E0    | lea ecx,dword ptr ss:[ebp-20]                    |

也就是这样.后面的操作就没什么意义了已经,所以这里我们就拿到了正确的结果了。开始写代码。

#include<iostream>
#include<string>

const char* str = "AKA-";

int main()
{
	std::string username;
	std::getline(std::cin, username);
	int nValue = username.length() * 0x17CFB + username[0];
	std::string strRet = str + std::to_string(nValue);
	std::cout << strRet << std::endl;
	return 0;
}

输出结果测试

Type In Your Name
AKA-1658111
weiran
AKA-585305

没问题了

补课多分析一些。

首先我先把重点函数给提取出来

0040253 | F7DE       | neg esi                                           |
0040254 | 1BF6       | sbb esi,esi                                       |
0040254 | 46         | inc esi                                           |
0040254 | F7DE       | neg esi                                           |

好了好了就这四行

代码 esi = 0 esi = 1 esi = -1
neg esi 0 cf = 0 -1 cf = 1 -1 cf = 0
sbb esi,esi 0 -1 -1
inc esi 1 0 0
neg esi FFFFFFF 0 0

所以这样就让所有的1或者-1都变成了 0 而0 变成了fffffff 这个就是结果了。所以当为0的时候跳转到一个其他打印,不为0时才跳转到正确的结果

posted @ 2024-12-19 10:55  未然king  阅读(2)  评论(0编辑  收藏  举报