实现方法如下:
- 查壳,用Exeinfo等查壳工具查壳,无壳直接反编译;
- 去壳,有壳用对应的去壳工具脱壳;
- 反编译源码,用VB Decompiler、VBParser反编译工具反,编译软件源码;
- 分析源码,找到License验证位置,如果源码简单能够编译,直接修改源码爆破;否则利用动态调试器修改P-code爆破;
- 利用动态调试器WKTVBDebugger来动态调试;
- 爆破,利用WKTVBDebugger修改P-code;
- WKTVBDebugger编译, 生成程序。
简单例子
爆破软件:娃娃的CCG CRACKME3
代码如下,用exdec反编译的,哦,如果静态分析有困难,可以用WKTVBDebugger,由于是在输入的同时进行验证,所以我们在EDIT上下断点,方法:用WKTVBDebugger打开crackme,点Form Manager,拉下拉框选择main,然后选择TEXTBOX,下拉框选择TEXT1,点BPX钮,OK,现在按F5执行程序,在输入框中输入任何东东,立刻断下来了:)于是到了这里….
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| 40EAAC: 04 FLdRfVar local_00E0 ==>push address这玩艺过会存放字符串的地址, 40EAAF: 21 FLdPrThis ==>这里我怀疑是取程序本身的句柄,不确定,请高手指点 40EAB0: 0f VCallAd (object 2 ) ==>之所以有上面的怀疑是因为这里wktvbdbg注释为 ==>main.text1,所以猜是调用某程序自身的函数 40EAB3: 19 FStAdFunc local_00DC 40EAB6: 08 FLdPr local_00DC 40EAB9: 0d VCallHresult id ==>get_ipropTEXTEDIT 得到输入字符串 40EABE: 3e FLdZeroAd local_00E0 ==>字符串地址指针 40EAC1: 46 CVarStr local_00F0 ==>复制指针到local_00F0 40EAC4: 04 FLdRfVar local_0100 ==>push函数参数,WKTVBdbg走到这里可以看 ==>locao_0100+8所指代的内存,那是你输入的东东 40EAC7: 0a ImpAdCallFPR4: ==>rtvTrimVar相当于what?VB高手告诉我这函数干嘛用的 ==>好吗? 40EACC: 04 FLdRfVar local_0100 ==>push字符串 40EACF: Lead0/eb FnLenVar ==>得到字符串长度 40EAD3: Lead1/f6 FStVar ==>将长度存到某处,哪里我没弄明白:( 40EAD7: 1a FFree1Ad local_00DC 40EADA: 36 FFreeVar ==>free... 40EAE1: f4 LitI2_Byte: 0x1 1 (.) ==>push 1 as byte??? 40EAE3: 04 FLdRfVar local_00D6 40EAE6: 04 FLdRfVar local_00D4 40EAE9: 55 CI2Var ==>这里应该是相当于计数器i了,当然是以刚才取的长度为... 40EAEA: Lead3/63 ForI2: (when done) 40EB5D==>靠,总算见着个确定的函数,for语句,都见过吧:) 40EAF0: 21 FLdPrThis ==>看看,又是一个,我刚才说过我的猜测了 40EAF1: 0f VCallAd (object 2 ) ==>某函数??? 40EAF4: 19 FStAdFunc local_00DC 40EAF7: 28 LitVarI2: ( local_0100 ) 0x1 (1)==>把常数1赋给local_0100,然后将此变量入栈 40EAFC: 6b FLdI2 local_00D6 ==>这里是计数器i 40EAFF: e7 CI4UI1 ==>似乎起符号扩展的作用,大伙看看 40EB00: 3e FLdZeroAd local_00DC 40EB03: Lead2/6f CVarAd 40EB07: 04 FLdRfVar local_0110 40EB0A: 0a ImpAdCallFPR4: ==>这里是rtcMidChar,这十几行就是Mid$(str,i,1) 40EB0F: 04 FLdRfVar local_0110 40EB12: Lead1/f6 FStVar 40EB16: 1a FFree1Ad local_00DC 40EB19: 36 FFreeVar 40EB20: 04 FLdRfVar local_0094 40EB23: Lead2/fe CStrVarVal local_00E0 ==>取得的字符地址入栈 40EB27: 0b ImpAdCallI2 ==>call rtcAnsiValueBstr,就是ASC$(char) 40EB2C: 44 CVarI2 local_0124 ==>字符的ASCII值 40EB2F: Lead1/f6 FStVar 40EB33: 2f FFree1Str local_00E0 40EB36: 04 FLdRfVar local_00B4 ==>这个应是返回值了 40EB39: 6b FLdI2 local_00D6 ==>当当当....当!计数器i出现,干什么用呢? 40EB3C: 44 CVarI2 local_0124 ==>哇,取得的字符也出现了 40EB3F: Lead0/94 AddVar local_00F0 ==>原来是加起来用啊 40EB43: Lead1/f6 FStVar 40EB47: 04 FLdRfVar local_00A4 ==>这个东东是sum 40EB4A: 04 FLdRfVar local_00B4 ==>这个东东是刚才的结果 40EB4D: Lead0/94 AddVar local_00F0 ==>两个东东加一起 40EB51: Lead1/f6 FStVar ==>放到local_00A4里面去.哦哦... 40EB55: 04 FLdRfVar local_00D6 ==>计数器i再次登场 40EB58: 64 NextI2: (continue) 40EAF0==>是否继续??? 40EB5D: 04 FLdRfVar local_00A4 ==>刚才我说过的sum 40EB60: 28 LitVarI2: ( local_0124 ) 0x6e4 (1764)==>一个常数0x6e4 40EB65: 5d HardType 40EB66: Lead0/33 EqVarBool ==>两者是否相等? 40EB68: 1c BranchF: 40EB94 ==>不等就错误了:) 40EB6B: 1b LitStr: "恭喜你..." 40EB6E: 21 FLdPrThis 40EB6F: 0f VCallAd (object 2 ) 40EB72: 19 FStAdFunc local_00DC 40EB75: 08 FLdPr local_00DC 40EB78: 0d VCallHresult 禚d ==>put _ipropTEXTEDIT写下几句肉麻的话^_* 40EB7D: 1a FFree1Ad local_00DC 40EB80: f4 LitI2_Byte: 0x0 0 (.) 40EB82: 21 FLdPrThis 40EB83: 0f VCallAd (object 1 ) 40EB86: 19 FStAdFunc local_00DC 40EB89: 08 FLdPr local_00DC 40EB8C: 0d VCallHresult 禚d
|
算法如下:
1 2 3
| int sum=0;int char,len; gets(str);len=strlen(str); for (int i=0;i if (sum==0x6e4) printf("Bingo,just so so");
|
呵呵,我就会弄些简单的糊弄人,没法,就这么大本事,还请各位海涵….
附:反正得凑个数,没什么目的性,就当成注册机写吧,其实写的时候也是迷迷糊糊,尽量保证不出现特殊字符吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| int main(){ int i,len,sum=0; char str[20]="bbbsl"; clrscr(); gets(str); len=strlen(str); for (i=0;i if (sum>0x6e4) printf("error name"); else{ sum=0x6e4-sum; do{ str[i]=0x41; sum-=(0x42+i); i++; }while((sum-0x42-i)>0x40); if (sum>0x7a+0x14) { sum-=40; str[i]=sum/2; str[i+1]=sum-str[i]-1; str[i+2]='\0'; }else{ sum-=20; str[i]=sum; str[i+1]='\0'; } puts (str); } return 0; }
|