破解NetScanTools Pro 2000及其InstallShield指令碼破解(其實指令碼沒破成) (18千字)
破解NetScanTools Pro 2000及其InstallShield指令碼破解(不完整)
Passion
我幾個星期前曾受被人尊稱為“皮大爺”的peterchen老兄的語無倫次的鞭策,於是也好高騖遠地想研究研究InstallShield的指令碼破解,正巧不久前見了洋白菜兄的InstallShield指令碼反編譯教程,覺得比一個位元組一個位元組地研究INS檔案的編譯後程式碼要方便多了,因而也就偷了許多懶。――NetScanTools
Pro 2000是一套功能非常全面的網路掃描監控工具,Northwest Performance公司開發,網址是http://www.nwpsw.com/,不過此處沒完整版下載。
NetScanTools Pro 2000安裝時需要輸入序列號,直接破據說非常麻煩,一個比較好的法子是從INS檔案入手。我在洋白菜兄的主頁crackbest.com上下了一個DIS(DeInstallShield),用它反編譯setup.ins檔案感覺還可以。
NetScanTools Pro 2000安裝程式會詢問姓名公司序列號,填完按NEXT後會出現一個框要你確認填的是否正確,按“Yes”後才進行序列號檢測,錯則彈出對話方塊說“Invalid
Serial Number。”沒的說,用DIS反編譯其SETUP.INS,在結果中找“Invalid Serial Number”的MSGREF訊息字串引用,很快就找到了下面的一段:
<LABEL_0038> REF: 00000F72
|
00002044: 00B6 START OF FUNCTION (2*StrLocals + 3*NumLocals)
00002054: 0013 StrVar[001C] = ""
0000205C: 0013 StrVar[001D] = ""
00002064: 0013 StrLocal[0001] = ""
0000206C: 0013 StrLocal[0002] = ""
00002074: 0002 Disable (00000032)
<LABEL_0039> REF: 00002147
|
0000207F: 0021 NumLocal[0002] = 00000000
0000208D: 0129 WHILE (NumLocal[0002] = 00000000)
000020AF: 00B5 NumLocal[0001] = SdRegisterUserEx_[LABEL_00B0]
(StrLocal[0001],StrLocal[0002],StrVar[001C],StrVar[001D],StrVar[001E])
000020CE: 00B5 NumLocal[0002] = SdConfirmRegistration_[LABEL_00E5]
(StrLocal[0001],StrVar[001C],StrVar[001D],StrVar[001E],00000000)
000020EF: 0000 ENDWHILE
//以上這個WHILE就是讓你輸入序列號並確認的。
00002108: 0128 IF (Call Function_006F_[LABEL_004D] != 00000001) THEN
~~~~這裡是不等於號
00002128: 002A MessageBox ("Invalid Serial Number",SEVERE)
//在此處引用MSG字串。
00002147: 002C Goto (LABEL_0039)
00002148: 0000 ENDIF
//然後呼叫LABEL_004D處的Function_006F來驗證序列號,如果返回值不是1就表示出錯,出現出錯對話方塊。
00002150: 012F Return (NumLocal[0001])
00002157: 00B8 END OF FUNCTION ()
因此這裡最簡單的想法是把00002108處的不等於改成等於,正巧DIS有這個功能,右鍵點選它選Change to,改成等於就行了。退出DIS的時候會提示是否重新校驗INS檔案,因為SETUP在執行時會首先檢測INS檔案的CRC校驗和,因此這裡修改後也要重新校驗,選“是”後新的INS檔案就產生了。
再執行NetScanTools Pro 2000的安裝程式,序列號亂填一氣,安裝透過。
按理說通常的安裝軟體,破到這個程度也就差不多了,但NetScanTools Pro 2000多做了一點小手腳。本來我還挺高興地執行NSTPRO.EXE想看看自己的成果,NSTPRO.EXE卻忽地彈出個視窗說是“Invalid
Installation……”並且要求重新安。?哇!看來NSTPRO.EXE啟動時還有一步序列號的判斷過程。序列號資訊存放在什麼地方呢?我連REGMON和FILEMON都懶得用了,直接開啟登錄檔尋尋覓覓就找到了這一處:HKEY_LOCAL_MACHINE\Software\Northwest
Performance Software, Inc.\NetScanTools Pro\2000\NETSCANTOOLSPRO,下面是輸入的使用者名稱和序列號等。
首先就覺得似乎從NSTPRO.EXE中分析序列號演算法還不如從INS檔案中分析來得簡單,既然指令碼中判斷序列號是否正確的子程式在LABEL_004D處,就把它的內容列出來看看啦:
<LABEL_004D> REF: 00002108
|
00002A92: 00B6 START OF FUNCTION (3*StrLocals + 10*NumLocals)
00002AA4: 0021 NumLocal[0005] = 00000081
//一個固定值
00002ABB: 0128 IF (StrLength (StrVar[001E]) < 00000018) THEN
00002ADB: 012F Return (00000000)
00002ADC: 0000 ENDIF
//如果序列號長度小於18H則出錯
00002AE8: 0128 IF (NumLocal[0006] > 00000019) THEN
00002B08: 012F Return (00000000)
00002B09: 0000 ENDIF
//長度大於19H也出錯,因此序列號只能是18H位或19H位。
00002B15: 0128 IF (NumLocal[0006] = 00000018) THEN
//如果長度是18H,則……
00002B35: 0021 NumLocal[0003] = 00000000
//N3是SL3的字串位置指標
00002B3F: 0021 NumLocal[0002] = 00000013
//N2是序列號的字串位置指標
<LABEL_0050> REF: 00002B9D
|
00002B4D: 0128 IF (NumLocal[0002] <= 00000017)
THEN
00002B6D: 007A NumLocal[0009] = GetByte
(StrVar[001E],NumLocal[0002])
//SV1E是使用者輸入的序列號
00002B78: 007B SetByte (StrLocal[0003],NumLocal[0003],NumLocal[0009])
00002B83: 0119 NumLocal[0003] = NumLocal[0003]
+ 00000001
00002B90: 0119 NumLocal[0002] = NumLocal[0002]
+ 00000001
00002B9D: 002C Goto (LABEL_0050)
00002B9E: 0000 ENDIF
//將SL3的值賦成序列號中的第13H位到17H位子串,該子串是數字。
00002BA6: 0021 NumLocal[0006] = 00000013
//並且N6記錄了該數字字串在序列號中出現的位置
00002BA7: 0000 ENDIF
//如果長度是19,則……
00002BB4: 0128 IF (NumLocal[0006] = 00000019) THEN
00002BD4: 0021 NumLocal[0003] = 00000000
00002BDE: 0021 NumLocal[0002] = 00000014
<LABEL_0053> REF: 00002C3C
|
00002BEC: 0128 IF (NumLocal[0002] <= 00000018)
THEN
00002C0C: 007A NumLocal[0009] = GetByte
(StrVar[001E],NumLocal[0002])
00002C17: 007B SetByte (StrLocal[0003],NumLocal[0003],NumLocal[0009])
00002C22: 0119 NumLocal[0003] = NumLocal[0003]
+ 00000001
00002C2F: 0119 NumLocal[0002] = NumLocal[0002]
+ 00000001
00002C3C: 002C Goto (LABEL_0053)
00002C3D: 0000 ENDIF
00002C45: 0021 NumLocal[0006] = 00000014
00002C46: 0000 ENDIF
00002C53: 0021 NumLocal[0002] = 00000000
//如果長度是19H,則取14H到18H位到SL3中。
<LABEL_0056> REF: 00002D5D
|
//到這裡為止,N2是下一步即將進行的處理中的字串指標
//下一步是個大迴圈。
00002C61: 007A NumLocal[0009] = GetByte (StrVar[001E],NumLocal[0002])
//N9是輸入序列號的某個字元
00002C6C: 011D NumLocal[0007] = 000000FF & NumLocal[0009]
//N7=N9 AND 0xFF,個人感覺N7實際上等於N9
00002C79: 0119 NumLocal[0002] = NumLocal[0002] + 00000001
00002C86: 0021 NumLocal[0003] = 00000000
//N3是迴圈變數,此處初始化
<LABEL_0057> REF: 00002D35
|
//以下是個小迴圈,處理序列號中的一個字元
00002C94: 0128 IF (NumLocal[0003] <= 00000007) THEN
00002CB4: 011D NumLocal[0009] = NumLocal[0005]
& 00000001
00002CC1: 011D NumLocal[000A] = NumLocal[0007]
& 00000001
00002CD9: 0022 IF (NumLocal[0009] ^ NumLocal[000A]
!= 00000000) THEN
00002CE7: 0122 NumLocal[0009] = NumLocal[0005]
>> 00000001
00002CF4: 011F NumLocal[0005] = NumLocal[0009]
^ 00008408
00002D01: 0000 ELSE
00002D0A: 0122 NumLocal[0005] = NumLocal[0005]
>> 00000001
00002D0B: 0000 ENDIF
00002D1B: 0122 NumLocal[0007] = NumLocal[0007]
>> 00000001
00002D28: 0119 NumLocal[0003] = NumLocal[0003]
+ 00000001
00002D35: 002C Goto (LABEL_0057)
00002D36: 0000 ENDIF
//小迴圈結束
00002D5D: 0022 IF (NumLocal[0006] - = 00000000) THEN GOTO LABEL_0056
//減一後等於0就跳回去繼續迴圈?不等呢就結束迴圈?這是疑點之一。
//大迴圈結束後開始驗證
00002D6B: 0120 NumLocal[0007] = NumLocal[0005] ~ NumLocal[0005]
00002D7E: 0121 NumLocal[0009] = NumLocal[0005] << 00000008
00002D8B: 0122 NumLocal[000A] = NumLocal[0007] >> 00000008
00002D98: 011D NumLocal[000A] = NumLocal[000A] & 000000FF
00002DA5: 011E NumLocal[0005] = NumLocal[0009] | NumLocal[000A]
00002DB0: 011D NumLocal[0005] = NumLocal[0005] & 0000FFFF
//最後的結果是N5,與SL3的數字值比較,等則表示輸入的序列號合法。
00002DCD: 0128 IF (StrToNum (NumLocal[0004],StrLocal[0003]) < 00000000)
THEN
00002DED: 012F Return (FFFFFFFF)
00002DEE: 0000 ENDIF
00002DFA: 0128 IF (NumLocal[0005] != NumLocal[0004]) THEN
00002E18: 012F Return (FFFFFFFF)
00002E21: 0000 ELSE
00002E2A: 012F Return (00000001)
00002E2B: 0000 ENDIF
00002E37: 00B8 END OF FUNCTION ()
上邊我能看懂的地方加了一些註釋,名為STRVAL的都是字串型全域性變數,名裡有local的都是區域性變數。StrVar[001E]是我們輸入的序列號。這個程式首先判斷序列號是否是18H或19H長,然後取出序列號的最後五個數字。程式末尾把運算的結果與這個五位數字值比較,不等則出錯。整個運算過程雖不長,卻有點不符合常規。――我手頭沒有詳細介紹INSTALLshield指令碼語法的資料,上次皮特陳兄雖做了一個,卻不敢看(老當機),只有猜測著來。與或非左右移等符號和C中差不多,IFWHILEENDIF等和VB又差不多。我按照我的理解編了一段C程式碼來模仿這段運算過程。先輸入19個字元(0到0x13),再把這些字元運算得到五位數字(0x13到0x17),但拼湊起來的序列號根本通不過。我一直以為是我的指令碼演算法理解錯誤,山窮水盡了好幾天也沒什麼結果(對自己的水平沒有自信啦)。
我也打算去找一個正確的序列號來驗證自己的想法,可這種軟體的這個版本的序列號在什麼啊嘶嗒啦唯嘶嗒上是找不到的。再後來,“我本善良”兄給了我一個能用的序列號9351324-005376-001-32602,確實後五位是數字,前19位應該是輸入的東西,只是前19位看起來有了許多限制,比如哪幾位是數字,哪一位是“-”等,這在指令碼里卻沒找到。
現在只有從NSTPRO.EXE入手分析讀登錄檔中序列號的一段了。老法子,彈出出錯框時切入TRW查輸入的序列號再下Bpm記憶體斷點,偏偏TRW不穩定,記憶體斷點又斷不了,我氣得扔下它不幹了。過了幾天,該忙的似乎應付了一點後,弄了個SOFTICE來,這下子穩定多了。――由於這段時間忙,搞點破解只能擠出時間來,經常是研究幾個小時又停幾天,這就叫“三天破解,兩天曬網”,這種不良的風氣值得批鬥。
後來透過幾個BPM斷點來到了這一段:
* Reference To: KERNEL32.lstrlenA, Ord:02A1h
|
:00438D10 FF15C0D24900 Call dword
ptr [0049D2C0]
:00438D16 83F818
cmp eax, 00000018
:00438D19 0F858D000000 jne 00438DAC
:00438D1F 8D8C2494000000 lea ecx, dword
ptr [esp+00000094]
* Possible Reference to String Resource ID=00019: "Edit the list of IP addresses
and Hostnames."
|
:00438D26 6A13
push 00000013
:00438D28 51
push ecx
:00438D29 E8C2210000 call
0043AEF0
:00438D2E 83C408
add esp, 00000008
:00438D31 8D942494000000 lea edx, dword
ptr [esp+00000094]
:00438D38 8D4C2418
lea ecx, dword ptr [esp+18]
:00438D3C 8BF0
mov esi, eax
:00438D3E 52
push edx
:00438D3F E848AB0400 call
0048388C
:00438D44 8D44241C
lea eax, dword ptr [esp+1C]
* Possible Reference to String Resource ID=00005: "Error getting host address:
%s"
|
:00438D48 6A05
push 00000005
:00438D4A 50
push eax
:00438D4B 8D4C2420
lea ecx, dword ptr [esp+20]
:00438D4F C684245C63000001 mov byte ptr [esp+0000635C],
01
:00438D57 E8E3440400 call
0047D23F //取序列號後五位子串
:00438D5C 50
push eax
:00438D5D 8D4C241C
lea ecx, dword ptr [esp+1C]
:00438D61 C684245863000002 mov byte ptr [esp+00006358],
02
:00438D69 E8A9AB0400 call
00483917
:00438D6E 8D4C241C
lea ecx, dword ptr [esp+1C]
:00438D72 C684245463000001 mov byte ptr [esp+00006354],
01
:00438D7A E89FAA0400 call
0048381E
:00438D7F 8B4C2418
mov ecx, dword ptr [esp+18]
:00438D83 51
push ecx
:00438D84 E8572F0300 call
0046BCE0
:00438D89 81E6FFFF0000 and esi, 0000FFFF
:00438D8F 83C404
add esp, 00000004
:00438D92 3BF0
cmp esi, eax
//此處EAX和ESI,一個是根據前多少位計算出來的校驗值,一個是序列號中後五位轉換成的數字值,所以這裡是一步比較關鍵的跳轉。
:00438D94 7502
jne 00438D98
:00438D96 33FF
xor edi, edi
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00438D94(C)
|
:00438D98 8D4C2418
lea ecx, dword ptr [esp+18]
:00438D9C C684245463000000 mov byte ptr [esp+00006354],
00
:00438DA4 E875AA0400 call
0048381E
:00438DA9 83CEFF
or esi, FFFFFFFF
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00438D19(C)
|
:00438DAC 8D942494000000 lea edx, dword
ptr [esp+00000094]
:00438DB3 52
push edx
* Reference To: KERNEL32.lstrlenA, Ord:02A1h
|
:00438DB4 FF15C0D24900 Call dword
ptr [0049D2C0]
:00438DBA 83F819
cmp eax, 00000019
:00438DBD 0F858D000000 jne 00438E50
:00438DC3 8D842494000000 lea eax, dword
ptr [esp+00000094]
* Possible Reference to String Resource ID=00020: "If checked, get latest
news from our website when first view"
|
:00438DCA 6A14
push 00000014
:00438DCC 50
push eax
:00438DCD E81E210000 call
0043AEF0
:00438DD2 83C408
add esp, 00000008
:00438DD5 8D8C2494000000 lea ecx, dword
ptr [esp+00000094]
:00438DDC 8BF0
mov esi, eax
:00438DDE 51
push ecx
:00438DDF 8D4C241C
lea ecx, dword ptr [esp+1C]
:00438DE3 E8A4AA0400 call
0048388C
:00438DE8 8D54241C
lea edx, dword ptr [esp+1C]
* Possible Reference to String Resource ID=00005: "Error getting host address:
%s"
|
:00438DEC 6A05
push 00000005
:00438DEE 52
push edx
:00438DEF 8D4C2420
lea ecx, dword ptr [esp+20]
:00438DF3 C684245C63000003 mov byte ptr [esp+0000635C],
03
:00438DFB E83F440400 call
0047D23F
:00438E00 50
push eax
:00438E01 8D4C241C
lea ecx, dword ptr [esp+1C]
:00438E05 C684245863000004 mov byte ptr [esp+00006358],
04
:00438E0D E805AB0400 call
00483917
:00438E12 8D4C241C
lea ecx, dword ptr [esp+1C]
:00438E16 C684245463000003 mov byte ptr [esp+00006354],
03
:00438E1E E8FBA90400 call
0048381E
:00438E23 8B442418
mov eax, dword ptr [esp+18]
:00438E27 50
push eax
:00438E28 E8B32E0300 call
0046BCE0
:00438E2D 81E6FFFF0000 and esi, 0000FFFF
:00438E33 83C404
add esp, 00000004
:00438E36 3BF0
cmp esi, eax
//這裡與上面的是一樣的,所不同的應該就是一個處理0X18位,一個處理0X19位。
:00438E38 7502
jne 00438E3C
:00438E3A 33FF
xor edi, edi
如果要找註冊碼運算的地方,可從前面跟進去到下面的這個地方(如果是0X18位序列號的話):
|
:00445DF7 6A13
push 00000013
:00445DF9 50
push eax
:00445DFA E8F150FFFF call
0043AEF0 //從這裡再跟進去。
:00445DFF 83C408
add esp, 00000008
:00445E02 8D4C241C
lea ecx, dword ptr [esp+1C]
:00445E06 8BF8
mov edi, eax
:00445E08 51
push ecx
:00445E09 8D4C2414
lea ecx, dword ptr [esp+14]
:00445E0D E87ADA0300 call
0048388C
:00445E12 8D542414
lea edx, dword ptr [esp+14]
從00445DFA處跟進CALL中,程式碼如下:
:0043AEF0 55
push ebp
:0043AEF1 8B6C240C
mov ebp, dword ptr [esp+0C]
//BP迴圈控制,目前是13,似乎對應著00002BA6: 0021 的NumLocal[0006] = 00000013
:0043AEF5 6685ED
test bp, bp
* Possible Reference to Dialog: DialogID_0081
|
:0043AEF8 B881000000 mov eax,
00000081
//這個0X81的常數是否有些眼熟?――就是INSTALLSHIELD反編譯指令碼中的
00002AA4: 0021 NumLocal[0005] = 00000081 哇!
:0043AEFD 7506
jne 0043AF05
:0043AEFF 66B87EFF
mov ax, FF7E
:0043AF03 5D
pop ebp
:0043AF04 C3
ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043AEFD(C)
|
:0043AF05 57
push edi
:0043AF06 8B7C240C
mov edi, dword ptr [esp+0C]
:0043AF0A 56
push esi
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043AF37(C)
|
:0043AF0B 8A0F
mov cl, byte ptr [edi] //讀一個字元
* Possible Reference to String Resource ID=00008: "Error connecting to host:
%s"
|
:0043AF0D BE08000000 mov esi,
00000008 //對每一個字元要進行八次迴圈。
//
:0043AF12 81E1FF000000 and ecx, 000000FF
//對應著
:00
相關文章
- pycharm 破解指令碼解析2024-06-11PyCharm指令碼
- python實現密碼破解2020-11-10Python密碼
- Tampermonkey油猴外掛破解資源:瀏覽器指令碼管理必備2024-01-02瀏覽器指令碼
- Locust 程式碼指令碼實現2024-03-16指令碼
- 2023 pycharm pro最新啟用碼「pycharm pro漢化破解版」2023-11-07PyCharm
- macbook pro破解UltraEdit2019-04-17Mac
- Macs Fan Control Pro中文破解版+Macs Fan Control Pro啟用碼2023-12-19Mac
- Shell指令碼最佳實踐2020-08-23指令碼
- ETL指令碼的實現2022-06-26指令碼
- 3.1 IDA Pro編寫IDC指令碼入門2023-11-11指令碼
- iOS逆向 Shell指令碼+指令碼重簽名2019-11-16iOS指令碼
- 常用指令碼學習手冊——Bat指令碼2023-04-05指令碼BAT
- 18 個一線工作中常用 Shell 指令碼2024-08-25指令碼
- Bash指令碼2018-12-10指令碼
- powershell指令碼2024-04-10指令碼
- jpsall指令碼2020-10-02指令碼
- perl指令碼2019-07-13指令碼
- shell指令碼2024-06-27指令碼
- MySQL指令碼2021-11-24MySql指令碼
- java 指令碼2020-12-28Java指令碼
- JMeter指令碼2020-12-07JMeter指令碼
- pycharm2017.3的破解碼2018-10-17PyCharm
- hadoop_批量命令指令碼&同步檔案指令碼2018-09-15Hadoop指令碼
- AE實用指令碼之——typemonkey2018-05-30指令碼
- 9個實用shell指令碼2022-10-19指令碼
- 【Linux】【Shell】主控指令碼實現2020-12-29Linux指令碼
- deepin 20 破解root密碼實戰--圖文2020-10-19密碼
- 初學指令碼2019-02-16指令碼
- python 常用指令碼2019-01-08Python指令碼
- Redis - Lua 指令碼2019-03-09Redis指令碼
- Linux指令碼分享2024-03-10Linux指令碼
- shell指令碼案例2024-04-06指令碼
- 19、python 指令碼2024-04-15Python指令碼
- SQLServer 常用指令碼2020-09-02SQLServer指令碼
- 備份指令碼2024-07-09指令碼
- 位元組碼指令2024-07-16
- 常用shell指令碼2024-05-30指令碼
- C# 指令碼2021-12-21C#指令碼
- MySQL 常用指令碼2023-01-09MySql指令碼