JProfiler?4.2?注冊(cè)分析
作者:舵手
申明:如轉(zhuǎn)載請(qǐng)保證文章的完整性以及出處
摘要:JProfiler是一款Java剖析器。JProfiler直觀的用戶界面能夠幫助你找到性能瓶頸,并指明你的內(nèi)存漏洞和解決線程問題。
????JProfiler是通過EXE來執(zhí)行,用十六進(jìn)制編輯器很容易找到程序的入口類:com.jprofiler.frontend.FrontendApplication?如果你要通過命令行運(yùn)行,得看看這個(gè)類的main方法,它需要兩個(gè)參數(shù)才能運(yùn)行。簡(jiǎn)單分析了一下該類,發(fā)現(xiàn)方法H完成了注冊(cè)碼的驗(yàn)證,讓我們順藤摸瓜找到計(jì)算注冊(cè)碼的位置。
????public?boolean?H()
????{
????????E?e1?=?com.jprofiler.frontend.E.H.A3().A2();
??//由于代碼經(jīng)過了混淆,以E命名的類有n多,所以千萬要找正確,否則會(huì)浪費(fèi)你的保寶貴時(shí)間
??//com.jprofiler.frontend.E.D.E——E的完整類路徑
????????int?i1?=?e1.A(null,?this);
????????switch(i1)
????????{
????????case?-2:?
????????????if(l())
????????????{
????????????????System.err.println("Your?license?key?has?expired.");
????????????????return?false;
????????????}
????????????int?j1?=?A(p,?"Your?license?key?has?expired.\nIf?you?were?not?able?to?evaluate?JProfiler,?
please\nrequest?a?new?key?at?"?+?L(),?new?String[]?{
????????????????"Enter?new?key",?"Send?mail"
????????????},?0);
????????????if(j1?==?1)
????????????{
????????????????O();
????????????????return?false;
????????????}
????????????if(!A(((String)?(null)),?true))
????????????????return?false;
????????????break;
????????case?-1:?
????????????break;
????????case?-3:?
????????????if(!A("Your?license?key?is?invalid.?Please?check?your?key.",?true))
????????????????return?false;
????????????break;
????????case?-5:?
????????????if(!A("There?was?an?error?communicating?with?the?license?server.\n
Please?check?your?license?key.",?true))
????????????????return?false;
????????????break;
????????case?-4:?
????????????if(!A("The?license?server?is?invalid.?\nPlease?check?your?license?key.",?true))
????????????????return?false;
????????????break;
????????case?-6:?
????????????A(com.jprofiler.frontend.E.D.C.B(),?false);
????????????return?false;
????????default:
????????????if(i1?<?0)
????????????????throw?new?RuntimeException("Unknown?license?status?"?+?i1);
????????????e1.A(i1);
????????????break;
????????}
????????e1.AA();
????????return?true;
????}
????如果讓e1.A(null,?this)返回-1,那問題就解決了。如果想暴破可以從這個(gè)方法入手,我們這里的任務(wù)是追出注冊(cè)算法:)
????首先我們跟進(jìn)com.jprofiler.frontend.E.H.A3().A2();這兩個(gè)方法,發(fā)現(xiàn)只是對(duì)類做一些初始化,我們略過。
????跟進(jìn)e1.A(null,?this),它又調(diào)用了重載方法A
????public?int?A(String?s,?C._A?_pa)
????{
????????return?A(s,?_pa,?true);
????}
????
????public?int?A(String?s,?C._A?_pa,?boolean?flag)
????{
????????if(s?==?null)
????????????s?=?F4;?//在該類初始化時(shí)已經(jīng)給F4給了值,如果注冊(cè)文件存在,該值為注冊(cè)碼
????????if(flag?&&?!s.startsWith("FLOAT:")?&&?!s.startsWith("S-"))
????????????com.A.A.E.C.A(s,?_pa);//跟進(jìn)這里,發(fā)現(xiàn)是網(wǎng)絡(luò)驗(yàn)證,由于我訪問不了IP?228.7.6.9?所以沒有詳細(xì)分析,
??????//有時(shí)間了再補(bǔ)上。如果你那里通不過網(wǎng)絡(luò)驗(yàn)證,把com.A.A.E.C$_B(C的內(nèi)部類)里的IP改一下應(yīng)該就沒問題
??????//可別問我怎么改,十六進(jìn)制編輯器就可以了:)
????????return?S(s);?//我們?cè)倏催@個(gè)方法
????}
????public?int?S(String?s)
????{
????????if(s?==?null)
????????????s?=?F4;//在該類初始化時(shí)已經(jīng)給F4給了值,如果注冊(cè)文件存在,該值為注冊(cè)碼
????????if(s.startsWith("FLOAT:"))?//不知道這代表什么,直覺上不是好東西,先不進(jìn)入,直接到else
????????{
????????????String?s1?=?s.substring("FLOAT:".length());
????????????int?i?=?-1;
????????????int?j?=?s1.lastIndexOf(':');
????????????if(j?>?-1)
????????????{
????????????????try
????????????????{
????????????????????i?=?Integer.parseInt(s1.substring(j?+?1));
????????????????}
????????????????catch(NumberFormatException?numberformatexception)?{?}
????????????????s1?=?s1.substring(0,?j);
????????????}
????????????int?k?=?C3();
????????????int?l?=?com.A.A.E.E.A(s1,?i,?k,?C7());
????????????FD?=?E.C();
????????????D(l?>?0?||?l?==?-1);
????????????return?l;
????????}?else
????????{
????????????return?Q(s);
????????}
????}
????Q(s)直接調(diào)用下面方法
????public?static?int?G(String?s)
????{//s為注冊(cè)碼
????????if(s?==?null)
????????????return?-3;
????????s?=?s.trim();
????????if(s.length()?<?3?||?s.charAt(1)?!=?'-'?||?s.indexOf('#')?==?-1)//長(zhǎng)度大于3,第二位字符必須為-,必段有#
????????????return?-3;
????????switch(s.charAt(0))//取注冊(cè)碼中的第一個(gè)字符
????????{
????????case?69:?//?'E'??試用版
????????????int?i?=?A(s);//查檢當(dāng)前日期是否過了試用期
????????????if(!F(s))
????????????????return?-3;
????????????else
????????????????return?i;
????????case?65:?//?'A'
????????case?76:?//?'L'//這三個(gè)有什么區(qū)別還沒有搞清
????????case?83:?//?'S'
????????????return?H(s);??//讓這里返回-1
????????}
????????return?-3;
????}
????private?static?int?H(String?s)
????{
????????if(B(s)?!=?2)//license串中的"-"必須等于兩個(gè),B函數(shù)的作用是計(jì)算串中的"-"字符的個(gè)數(shù)
????????????return?-3;
????????return?F(s)???-1?:?-3;//這里F必須反回true
????}
????private?static?boolean?F(String?s)
????{
????????A?a?=?new?A(s);//傳入注冊(cè)碼,進(jìn)行截取處理
????????if(!a.E())
????????????return?false;
????????String?s1?=?a.A();//返回注冊(cè)碼中第二個(gè)“-”后的所有字符
????????String?s2?=?E(s1);//把上面得到的字符串以“#”為界分開,“#”前的給s2
????????String?s3?=?D(s1);//“#”后的給s3
????????if(s3?==?null?||?s2?==?null)
????????????return?false;
????????else
????????????return?A(s3,?s2,?11,?7,?29);//重點(diǎn)所在
????}
????protected?static?boolean?A(String?s,?String?s1,?int?i,?int?j,?int?k)
????{
????????char?ac[]?=?s1.toCharArray();“#”前的串轉(zhuǎn)換為char
????????int?l?=?0;
????????char?ac1[]?=?ac;
????????int?i1?=?ac1.length;
????????for(int?j1?=?0;?j1?<?i1;?j1++)
????????{
????????????char?c?=?ac1[j1];
????????????l?+=?c;?//累加
????????}
????????String?s2?=?String.valueOf(l?%?i)?+?String.valueOf(l?%?j)?+?String.valueOf(l?%?k);
??//分別模11、7、29,結(jié)果相加,結(jié)果要和“#”后的那部分相等
????????return?s.equals(s2);
????}
????到這里我們已經(jīng)知道注冊(cè)的算法了,其實(shí)很簡(jiǎn)單:注冊(cè)碼必須以A、S、L其中一個(gè)字母開頭,第二個(gè)字符必須為“-”,“-”字符必須為兩個(gè),至少一個(gè)“#”字符,從目前的分析可以看出注冊(cè)碼長(zhǎng)度已以大于等于四了,程序代碼中<3時(shí)完蛋。接下來載取注冊(cè)碼中從第二個(gè)“-”字符位置加1開始到“#”前一個(gè)字符的子串,轉(zhuǎn)換為char后累加,再分別模11、7、29,把三次模運(yùn)算的結(jié)果相加,這個(gè)值等于注冊(cè)碼中“#”后面的所有字符。
????下面給寫出它的注冊(cè)機(jī)
import?java.util.*;
/**
?*?<p>Title:?JProfiler4.2?注冊(cè)機(jī)</p>
?*?<p>Description:?每執(zhí)行一次得到一個(gè)注冊(cè)碼</p>
?*?<p>Copyright:?Copyright?()?2006</p>
?*?@author?舵手
?*?@version?1.0
?*/
public?class?jprofiler4_keygen??
{
??public?static?void?main(String[]?args)?
??{
????String?s1?=?"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
????String?s2?=?"ALS";
????String?license?=?"";
????String?key?=?"";
????Random?rd?=?new?Random();
????int?j?=?rd.nextInt(3);
????license?+=?s2.substring(j,j+1)+"--";
????for?(int?i?=0?;?i?<?12?;?i++?)
????{
??????j?=?rd.nextInt(62);
??????license?+=?s1.substring(j,j+1);
??????key?+=?s1.substring(j,j+1);
????}
????license?+=?"#";
????char?ac[]?=?key.toCharArray();
????????int?l?=?0;
????????char?ac1[]?=?ac;
????????int?i1?=?ac1.length;
????????for(int?j1?=?0;?j1?<?i1;?j1++)
????????{
????????????char?c?=?ac1[j1];
????????????l?+=?c;
????????}
????????String?s3?=?String.valueOf(l?%?11)?+?String.valueOf(l?%?7)?+?String.valueOf(l?%?29);
????license?+=?s3;
????System.out.println(license);
??}
}
????通過上面的分析,我們可以用正則表達(dá)式表示出注冊(cè)碼[A|L|S]-.-[a-zA-Z0-9]#[0-9],第二個(gè)“-”后的字符到“#”字符前的字符串的長(zhǎng)度并沒有限制,當(dāng)然,不能為0,我只測(cè)試了長(zhǎng)度為1和12,計(jì)算的注冊(cè)碼都沒有問題,有興趣的可以多試幾個(gè):)“.”這個(gè)位置可以插入任意長(zhǎng)度的任意字符。
????從注冊(cè)算法上說,這個(gè)程序的保護(hù)很簡(jiǎn)單,但如果加上混淆和錯(cuò)綜復(fù)雜的方法調(diào)用,會(huì)讓你頭痛好一陣子。這里我只列出了和計(jì)算注冊(cè)碼有關(guān)的一些方法,而在實(shí)際跟蹤中,牽扯到的類和方法數(shù)量是很大的,這就需要耐心。我一直以來都認(rèn)為這樣的文章對(duì)那些想要從這里學(xué)到東西的人沒有什么用處,因?yàn)檫@種文章充其量只能算是授人以魚而不是授人以漁。對(duì)那些正在分析這個(gè)軟件的注冊(cè)算法的人來說,也許有那么一點(diǎn)點(diǎn)用處:)
????分析這個(gè)軟件的注冊(cè)只是個(gè)人愛好,由于水平有限,錯(cuò)誤疏漏在所難免,歡迎大家提出寶貴意見!