hjm666 发表于 2018-6-11 22:54

练手 160个CrackMe 之024

这个程序花了我好多时间···绕了我好久没想明白的····难度难···总算是完功了!加油!!


一、基础信息
                                                   


   只有一个About键位可以用,About 旁边是程序注册成功与否···   
                  About 也只是一个提示信息,,,,





   汇编写的(大佬········)并没有加壳


二、暴力破解
   此程序要破解怕是只有强行打补丁了,打补丁的话比较简单,也就不演示了,具体可以论坛找怎么打补丁·····(而且只用来打补丁的话太可惜了这个CM)......


三、注册机探寻


emmmmm   这就是重点的重点了····{:301_977:}    下面就是一段血泪史····


由于是汇编写的没有什么软件可以直接找到G点,就靠手法了···(调试完这个软件后我收回上面的大佬敬语····· 软件打开后根本关不了好吧{:301_1006:},
重点是调试着的时候,指不定什么时候打开程序的地址就错乱,我OD的这个程序缓存就没了,还好重点代码没有多少,不然我肯定炸{:301_1005:})


找关键代码 我们一般可以从API入手 Getwindowtext 读取输入框字符函数入手 ,或者直接智能搜索中文·····
0040129A   .E8 AF010000   call <jmp.&USER32.GetWindowTextA>      ; \GetWindowTextA
0040129F   .85C0          test eax,eax
004012A1   .74 48         je short Chafe_2.004012EB                ;没有读取到字符就跳
004012A3   .A1 0B304000   mov eax,dword ptr ds:          ;40300B == 58455443 是一个常量
004012A8   .BB 6C314000   mov ebx,Chafe_2.0040316C
004012AD   >0303          add eax,dword ptr ds:
004012AF   .43            inc ebx
004012B0   .81FB 7C314000 cmp ebx,Chafe_2.0040317C
004012B6   .^ 75 F5         jnz short Chafe_2.004012AD               ;eax + ebx(用户名地址)循环用户名字符长度次,每次地址加一
004012B8   .5B            pop ebx                                  ;kernel32.7C817077
004012B9   .03C3          add eax,ebx                              ;ebx是序列号的16进制
004012BB   .3105 D9124000 xor dword ptr ds:,eax          ;4012D9== 584554
004012C1   .C1E8 10       shr eax,0x10                           ;向右位移 0x10
004012C4   .66:2905 D9124>sub word ptr ds:,ax            ;将word ptr ds:值写入程序
004012CB   .BE EC114000   mov esi,Chafe_2.004011EC
004012D0   .B9 3E000000   mov ecx,0x3E
004012D5   .33DB          xor ebx,ebx
004012D7   .EB 04         jmp short Chafe_2.004012DD
004012D9   >54            push esp         ;改代码处
004012DA      45            db 45                                    ;CHAR 'E'   ;改代码处
004012DB      58            db 58                                    ;CHAR 'X'   ;改代码处
004012DC      00            db 00
004012DD   >AD            lods dword ptr ds:                  ;从程序esi地址处取值
004012DE   .33D8          xor ebx,eax                              ;异或,初始ebx ==0
004012E0   .49            dec ecx
004012E1   .^ 75 FA         jnz short Chafe_2.004012DD               ;循环3E次,每次esi地址加4
004012E3   .81FB FBCFFCAF cmp ebx,0xAFFCCFFB
004012E9   .^ 74 EE         je short Chafe_2.004012D9
004012EB   >68 59304000   push Chafe_2.00403059                  ; /Your serial is not valid.
004012F0   .FF35 5C314000 push dword ptr ds:             ; |hWnd = NULL
004012F6   .E8 7D010000   call <jmp.&USER32.SetWindowTextA>      ; \SetWindowTextA
004012FB   .33C0          xor eax,eax
004012FD   .C9            leave
004012FE   .C2 1000       retn 0x10
00401301   .68 73 30 40 0>ascii "hs0@",0                           ;YES! You found your serial!!
00401306   .FF35 5C314000 push dword ptr ds:             ; |hWnd = NULL
0040130C   .E8 67010000   call <jmp.&USER32.SetWindowTextA>      ; \SetWindowTextA




   具体过程有点绕。。。。。 我上一张好理解的流程图

   明白了程序是再修改自身代码跳转到正确地方时,我想到了 JMP 无条件跳转,可以不考虑标志位情况,简单且粗暴!! {:301_993:}
004012D9 处我手动修改代码 JMP 到004012FE 得到EB26


了解了程序的大概流程我尝试了正推注册码,发现 eax 右移后 又经过写入地址 004012D9 处,还缺少条件和值来推算正确流程··· 我们必须要先搞明白后面的二次验证来追踪004012D9值的变化··


大概分析流程
一、3E次循环异或后值与0xAFFCCFFB相等时,此时004012D9的值必定是正确的,它是多少?


二、根据分析用户名运算过后的值加序列号的16进制的最终结果 004012BB   .3105 D9124000 xor dword ptr ds:,eax   的eax值是固定的,根据第一步中的到的sub的值推算出来


三、这个eax减去用户名运算的值得到序列号的16进制


祥:
一:
       第二次验证中最重要的是 在循环读取程序的值中,其中004012D9的值是后来经过程序一段操作后写入程序内的是不可知,和猜测的,而且004012D9 地址的值包含了这个二次验证中取的地址的值中两个有影响,这两个地址的值影响着
异或后是否等于 0xAFFCCFFB ,
    跟据异或的特性: A^B=C->A=B^C我们可以来推算
         因为我们只受 004012D8 和 004012DC地址影响,我们可以在OD中直接调试到004012D8前的值,其中调试时发现有个坑····我跳进去了很久···直到发现才·····
             在程序004011EC 到 004011EC+3E*4 的地址中调试读取这些地址是千万不要留下断点。。不然 取的值有两个位会变成 cc
   最后得到A213FCEE^   xxxxxx04^ D833ADxx ^ 81FA7549 =AFFCCFFB(追过数据的人一定看得懂,一定很熟悉,都是泪。。。{:301_972:})   精简一下后 -》 8C15465C =XXXXXX04 ^ D833ADXX
因为程序最后还要再 004012D9地位写入 26EB (EB26堆栈的存储形式) 再得到 --》 8C15465C =XX26EB04 ^ D833ADXX    <关键运算 : 8C=D8^ XX ;4 =XX^5C> 填位得到 5426EB04和 D833AD58最后写入到004012D9的值是 585426EB


二、再逆推就变成    eax ^00584554 =5854xxxx   先算eax的高位xxxx=0058^5854-> 580C   算eax的低位时要理清004012D9 低位26EB 怎么来的    计算 -》 低位26EB 加上 eax的高位 580C --> 3BA3最终得到这个用户名的运算结果和序列号的值
0x580C3BA3


(反正看字面上有点绕,跟了代码的应该看的懂,已经尽量述说简单化,应该好理解··)   
A213FCEE^   xxxxxx04^ D833ADxx ^ 81FA7549 =AFFCCFFB(分成了4块 004012D8以前的异或值为一块 ,因为到004012D8时循环到倒数第4个了,两个未知值个为一块,最后循环的值为一块··)




注册机:
#include<iostream>
using namespacestd;
unsigned long a=0x58455443;
unsigned long key=0x580C3BA3;
void main()
{

        char name ={0};
        cout << "Input yous name : " <<endl;
        cin >> name ;
        int len =strlen(name);
        for (int i=0;i<len;i++)
        {
                void *p=&name;
                _asm
                {
                        mov ebx, p;
                        mov eax, dword ptr;
                        add a , eax;
                }
        }
        cout << hex<<a <<endl;
        key=key - a ;
        cout << "The key is :\n"<<dec<<key<<endl;
        system("pause");
}


奉上一个:


还有很多不足的地方还是要多学·····
软件 :


    如有错误还望大佬指出 ,不胜感激!!!!!

ahmeijian 发表于 2018-6-12 12:24

新手学习,谢谢

xiayan0310 发表于 2018-6-12 16:43

问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热

薛定谔的猫i 发表于 2018-6-12 21:51

感谢分享

jmpengbo 发表于 2018-6-12 22:00

感谢分享

willrean 发表于 2018-6-13 15:38

学习了 谢谢楼主

zx729215749 发表于 2018-6-16 22:42

感谢分享!
页: [1]
查看完整版本: 练手 160个CrackMe 之024