前言:一开始写的时候不太懂,随着边分析边写到最后自己重新分析了下汇编指令,也懂了shark恒老师为什么说0040136B这个是关键的,文章自己也不改了,可能看起来会牛头不对马嘴,因为一开始不太懂也再写,最后懂了才把后面的内容写上
shark恒老师在判断序列号到结束的流程都走了一遍,自己也尝试着走了一遍然后记录下了这些
004012FE . E8 4D030000 call <jmp.&USER32.GetDlgItemTextA> GetDlgItemTextA 获取文本内容
00401303 . C745 F0 00000>mov dword ptr ss:[ebp-0x10],0x0 将0x0赋值给ebp-0x10地址的机器码
0040130A . B8 22124000 mov eax,硬编码寻.00401222 将00401222地址赋给eax寄存器中
0040130F . 8B10 mov edx,dword ptr ds:[eax] 将当前eax中的前四个字节地址中的机器码赋值给edx
00401311 . 8955 D0 mov dword ptr ss:[ebp-0x30],edx 将edx中储存的机器码赋值给ebp-0x30地址中的机器码
00401314 . 8B50 04 mov edx,dword ptr ds:[eax+0x4] 将eax+0x4的地址中前四个字节的机器码赋值给edx
00401317 . 8955 D4 mov dword ptr ss:[ebp-0x2C],edx 将edx的地址给ebp-0x2C
0040131A . 8B40 08 mov eax,dword ptr ds:[eax+0x8] 将eax+0x8的地址中的机器码赋值给eax寄存器
0040131D . 8945 D8 mov dword ptr ss:[ebp-0x28],eax 将eax中的机器码赋值给 ebp-0x28的前四个字节
00401320 . 8D45 DC lea eax,dword ptr ss:[ebp-0x24] 将ebp-0x24的地址赋值给eax
00401323 . 83C4 FC add esp,-0x4 堆栈平衡
00401326 . 6A 08 push 0x8
00401328 . 6A 00 push 0x0
0040132A . 50 push eax
0040132B . E8 F0020000 call <jmp.&msvcrt.memset> call memset开辟内存空间
00401330 . 83C4 10 add esp,0x10 堆栈平衡
00401333 . C745 CC 00000>mov dword ptr ss:[ebp-0x34],0x0 将0x0赋值给ebp-0x34
0040133A . 8DB6 00000000 lea esi,dword ptr ds:[esi] 不变
00401340 > 83C4 F4 add esp,-0xC 堆栈平衡
00401343 . 8D45 D0 lea eax,dword ptr ss:[ebp-0x30] 将ebp-0x30地址赋值给eax
00401346 . 50 push eax 压入eax (推测用来才能出下方strlen返回的字符长度)
00401347 . E8 DC020000 call <jmp.&msvcrt.strlen> call strlen
0040134C . 83C4 10 add esp,0x10 堆栈平衡
0040134F . 89C0 mov eax,eax
00401351 . 8D50 FF lea edx,dword ptr ds:[eax-0x1]
00401354 . 3955 F0 cmp dword ptr ss:[ebp-0x10],edx 比较edx中的值和ebp-0x10中的值
00401357 . 72 07 jb short 硬编码寻.00401360 jb判断上面edx中的值是否小于0240FAC0的值,小于则跳转
00401359 . EB 35 jmp short 硬编码寻.00401390
0040135B 90 nop
0040135C 8D7426 00 lea esi,dword ptr ds:[esi]
00401360 > 8B45 F4 mov eax,dword ptr ss:[ebp-0xC] 将ebp-0xc地址的值赋值给eax
00401363 . 8B55 F0 mov edx,dword ptr ss:[ebp-0x10] 将ebp-0x10地址的值赋值给edx
00401366 . 01D0 add eax,edx 不变
00401368 . 0FBE10 movsx edx,byte ptr ds:[eax] movsx指令 将eax地址中的第一个字节的值赋值给edx,再用0填充
0040136B . 8D42 EC lea eax,dword ptr ds:[edx-0x14] 将edx-0x14地址 赋值给eax
0040136E . 8D55 D0 lea edx,dword ptr ss:[ebp-0x30] 将ebp-0x30 地址赋值给edx
00401371 . 8B4D F0 mov ecx,dword ptr ss:[ebp-0x10] 将ebp-0x10的地址中的机器码赋值给ecx
00401374 . 0FBE1411 movsx edx,byte ptr ds:[ecx+edx] movsx 把ecx+edx中的值的第一个字节中的机器码赋值给edx,并且根据符号位进行填充
00401378 . 39D0 cmp eax,edx cmp进行edx和eax的比较
0040137A . 75 0D jnz short 硬编码寻.00401389 jnz进行跳转
0040137C . 8D45 D0 lea eax,dword ptr ss:[ebp-0x30] 将ebp-0x30的值,赋值给eax
0040137F . 8B55 F0 mov edx,dword ptr ss:[ebp-0x10] 将ebp-0x10的值赋值给edx
00401382 . C60402 73 mov byte ptr ds:[edx+eax],0x73 把0x73赋值给edx+eax的地址第一个字节的值
00401386 . FF45 CC inc dword ptr ss:[ebp-0x34] 自增ebp-0x34的值
00401389 > FF45 F0 inc dword ptr ss:[ebp-0x10] 自增ebp-0x10的值
0040138C . EB B2 jmp short 硬编码寻.00401340 直到这里判断结束
0040138E 89F6 mov esi,esi
00401390 > B8 2E124000 mov eax,硬编码寻.0040122E ASCII "正确!"
....
004013B9 . B8 37124000 mov eax,硬编码寻.00401237 ASCII "错误!"
跟了一次,发现自己还是很迷糊,不清楚shark恒老师为什么能找到0040136B . 8D42 EC lea eax,dword ptr ds:[edx-0x14]
是关键点,先留着吧
自己的想法实践:
1、因为真码和假码肯定会进行比较,所以自己就先把自己认为关键的比较cmp指令进行F2断点,然后进行观察
2、然后再次猜想,自己下的第一个断点是跳转向正确和错误的,并且第二个断点会进行判断多次,所以猜想第一个断点是当比较次数完了之后才进行下面的成功与失败的处理,那么自己就在第二个断点继续观察
,发现在其中自己输入的数值会与其他数值进行比较
edx=0000001D
eax=0000001D
自己输入的11111111111,其机器码就为0000001D,多次运行,发现只有上面的再进行改变,所以进行怀疑上面的多个机器码为真码
3、记录下多次比较,然后发现是1D 1E 1F 44 61 51 3C 5B 36 55 51 那么我们只需要分析上面的汇编指令就可以了
4、重新分析下汇编指令的含义
00401360 > 8B45 F4 mov eax,dword ptr ss:[ebp-0xC] 把存放的是假码的地址的值赋值给eax
00401363 . 8B55 F0 mov edx,dword ptr ss:[ebp-0x10] 清空edx
00401366 . 01D0 add eax,edx 无意义
00401368 . 0FBE10 movsx edx,byte ptr ds:[eax] 将假码的地址的第一个字节的值赋值给edx
0040136B . 8D42 EC lea eax,dword ptr ds:[edx-0x14] 把假码的机器码,减去14 再放到eax中
0040136E . 8D55 D0 lea edx,dword ptr ss:[ebp-0x30] 可疑字符串的地址存放到edx中
00401371 . 8B4D F0 mov ecx,dword ptr ss:[ebp-0x10] 清空ecx
00401374 . 0FBE1411 movsx edx,byte ptr ds:[ecx+edx] 将假码的第一个字节放在edx中
00401378 . 39D0 cmp eax,edx 假码和可疑字符串进行比较
关键0040136B . 8D42 EC lea eax,dword ptr ds:[edx-0x14] 把假码的机器码,减去14 再放到eax中
那么我们只需要在原来比较的可以字符串+0x14 算出来的则是真码,经过计算后的值为31 32 33 58 75 65 50 6F 4A 69 65