【原創】一個彩票軟體演算法分析過程(詳細)

看雪資料發表於2015-11-15

有殼,UPX簡單加殼,用OD就可以簡單脫
此軟體是重新驗證,註冊碼是32位的,有數字,有大寫字母,就是16進位制組成的。
如果你的輸入碼經過計算等於機器碼……已註冊,  
我輸入的12345678901234561234567890123456    我的機器碼1UI0IN58980863NE
在它輸入註冊碼之後存入Reg.Dll,我們可以查詢字串Reg.Dll
找到兩處,一處是

00501820   |.  BA CC185000 mov edx,12_.005018CC                     ;  ASCII "Reg.Dll"
此處是儲存時用的,你可以開啟同目錄下的Reg.Dll看看,你輸的註冊碼就在裡面

004F57BC   |.  BA B85C4F00 mov edx,12_.004F5CB8                     ;  ASCII "Reg.Dll"
這樣我就在004F57BC下斷點
CTRL+F2重新來過,
F9執行,就中斷在004F57BC處,

004F57BC   |.  BA B85C4F00 mov edx,12_.004F5CB8                     ;  ASCII "Reg.Dll"
004F57C1   |.  8D86 780A00>lea eax,dword ptr ds:[esi+A78]
004F57C7   |.  E8 F8D7F0FF call 12_.00402FC4
004F57CC   |.  8D86 780A00>lea eax,dword ptr ds:[esi+A78]
004F57D2   |.  E8 7DD5F0FF call 12_.00402D54
004F57D7   |.  E8 CCD1F0FF call 12_.004029A8
004F57DC   |.  8D9E 780A00>lea ebx,dword ptr ds:[esi+A78]
004F57E2   |.  8D96 740A00>lea edx,dword ptr ds:[esi+A74]
004F57E8   |.  8BC3        mov eax,ebx
004F57EA   |.  E8 B1DBF0FF call 12_.004033A0
004F57EF   |.  8BC3        mov eax,ebx
004F57F1   |.  E8 16DCF0FF call 12_.0040340C
004F57F6   |.  E8 ADD1F0FF call 12_.004029A8
004F57FB   |.  8D86 780A00>lea eax,dword ptr ds:[esi+A78]
004F5801   |.  E8 86D8F0FF call 12_.0040308C
004F5806   |.  E8 9DD1F0FF call 12_.004029A8
004F580B   |.  8D4D BC     lea ecx,dword ptr ss:[ebp-44]
004F580E   |.  66:BA FE07  mov dx,7FE
004F5812   |.  8B86 740A00>mov eax,dword ptr ds:[esi+A74]
004F5818   |.  E8 EF9EFFFF call 12_.004EF70C                        ;  演算法關鍵點
004F581D   |.  8B55 BC     mov edx,dword ptr ss:[ebp-44]
004F5820   |.  8B86 700A00>mov eax,dword ptr ds:[esi+A70]
004F5826   |.  E8 B1F6F0FF call 12_.00404EDC                        ;  直接比較了
004F582B   |.  75 2C       jnz short 12_.004F5859                      跳轉關鍵點
004F582D   |.  33D2        xor edx,edx
004F582F   |.  8B86 540900>mov eax,dword ptr ds:[esi+954]
004F5835   |.  E8 5282F6FF call 12_.0045DA8C
004F583A   |.  BA C85C4F00 mov edx,12_.004F5CC8

……………………………………………………………………………………………………
進入004F5818
004EF70C   /$  55          push ebp
004EF70D   |.  8BEC        mov ebp,esp
004EF70F   |.  83C4 F8     add esp,-8
004EF712   |.  53          push ebx
004EF713   |.  56          push esi
004EF714   |.  57          push edi
004EF715   |.  33DB        xor ebx,ebx
004EF717   |.  895D F8     mov dword ptr ss:[ebp-8],ebx
004EF71A   |.  894D FC     mov dword ptr ss:[ebp-4],ecx
004EF71D   |.  8BF2        mov esi,edx
004EF71F   |.  8BD8        mov ebx,eax
004EF721   |.  33C0        xor eax,eax
004EF723   |.  55          push ebp
004EF724   |.  68 D3F74E00 push 12_.004EF7D3
004EF729   |.  64:FF30     push dword ptr fs:[eax]
004EF72C   |.  64:8920     mov dword ptr fs:[eax],esp
004EF72F   |.  8D55 F8     lea edx,dword ptr ss:[ebp-8]
004EF732   |.  8BC3        mov eax,ebx
004EF734   |.  E8 03FFFFFF call 12_.004EF63C                  ;  把輸入的註冊碼轉換一下
004EF739   |.  8B45 FC     mov eax,dword ptr ss:[ebp-4]
004EF73C   |.  8B55 F8     mov edx,dword ptr ss:[ebp-8]       ;  儲存地址放入EDX
004EF73F   |.  E8 E053F1FF call 12_.00404B24
004EF744   |.  8B45 F8     mov eax,dword ptr ss:[ebp-8]       ;  儲存地址放入EAX
004EF747   |.  E8 4456F1FF call 12_.00404D90                  ;  位數的一半給EAX說明要計算16次
004EF74C   |.  8BF8        mov edi,eax
004EF74E   |.  85FF        test edi,edi                       ;  註冊碼是否為空
004EF750   |.  7E 6B       jle short 12_.004EF7BD
004EF752   |.  BB 01000000 mov ebx,1
004EF757   |>  8B45 F8     /mov eax,dword ptr ss:[ebp-8]      ;  下面是把輸入的註冊碼進行計算
004EF75A   |.  8A4418 FF   |mov al,byte ptr ds:[eax+ebx-1]    ;  得到第1,2個上面算好的註冊碼
004EF75E   |.  0FB7D6      |movzx edx,si                      ;  第一次是固定值07EE
004EF761   |.  C1EA 08     |shr edx,8                         ;  固定值右移2位還有2位
004EF764   |.  32C2        |xor al,dl                         ;  右移的值與前兩位異或
004EF766   |.  84C0        |test al,al                        ;  比較是否等於0
004EF768   |.  75 1F       |jnz short 12_.004EF789
004EF76A   |.  8B45 FC     |mov eax,dword ptr ss:[ebp-4]
004EF76D   |.  E8 7658F1FF |call 12_.00404FE8
004EF772   |.  8B55 F8     |mov edx,dword ptr ss:[ebp-8]
004EF775   |.  8A541A FF   |mov dl,byte ptr ds:[edx+ebx-1]
004EF779   |.  885418 FF   |mov byte ptr ds:[eax+ebx-1],dl
004EF77D   |.  66:6BC6 0B  |imul ax,si,0B
004EF781   |.  66:83C0 0C  |add ax,0C
004EF785   |.  8BF0        |mov esi,eax
004EF787   |.  EB 30       |jmp short 12_.004EF7B9
004EF789   |>  8B45 FC     |mov eax,dword ptr ss:[ebp-4]
004EF78C   |.  E8 5758F1FF |call 12_.00404FE8                 ;  產生一個儲存的地址
004EF791   |.  8B55 F8     |mov edx,dword ptr ss:[ebp-8]      ;  輸入碼地址
004EF794   |.  8A541A FF   |mov dl,byte ptr ds:[edx+ebx-1]    ;  得到兩位輸入碼
004EF798   |.  0FB7CE      |movzx ecx,si                      ;  得到固定值
004EF79B   |.  C1E9 08     |shr ecx,8                         ;  取固定值前2位
004EF79E   |.  32D1        |xor dl,cl                         ;  固定值的前兩位與兩位輸入碼XOR準備儲存
004EF7A0   |.  885418 FF   |mov byte ptr ds:[eax+ebx-1],dl    ;  儲存,其中EAX是004EF78C的CALL算出來的
004EF7A4   |.  8B45 F8     |mov eax,dword ptr ss:[ebp-8]      ;  得到輸入碼地址
004EF7A7   |.  0FB64418 FF |movzx eax,byte ptr ds:[eax+ebx-1] ;  再次得到前兩位輸入碼
004EF7AC   |.  66:03F0     |add si,ax                         ;  得到的輸入碼兩位與固定值相加
004EF7AF   |.  66:6BC6 0B  |imul ax,si,0B                     ;  上面得到的值與0B相乘,結果給AX
004EF7B3   |.  66:83C0 0C  |add ax,0C
004EF7B7   |.  8BF0        |mov esi,eax                       ;  再加0C作為下一次的固定值
004EF7B9   |>  43          |inc ebx
004EF7BA   |.  4F          |dec edi
004EF7BB   |.^ 75 9A       \jnz short 12_.004EF757
004EF7BD   |>  33C0        xor eax,eax
004EF7BF   |.  5A          pop edx
004EF7C0   |.  59          pop ecx
004EF7C1   |.  59          pop ecx
004EF7C2   |.  64:8910     mov dword ptr fs:[eax],edx
004EF7C5   |.  68 DAF74E00 push 12_.004EF7DA
004EF7CA   |>  8D45 F8     lea eax,dword ptr ss:[ebp-8]
004EF7CD   |.  E8 FE52F1FF call 12_.00404AD0
004EF7D2   \.  C3          retn
004EF7D3    .- E9 984BF1FF jmp 12_.00404370
004EF7D8    .^ EB F0       jmp short 12_.004EF7CA
004EF7DA    .  5F          pop edi
004EF7DB    .  5E          pop esi
004EF7DC    .  5B          pop ebx
004EF7DD    .  59          pop ecx
004EF7DE    .  59          pop ecx
004EF7DF    .  5D          pop ebp
004EF7E0    .  C3          retn

……………………………………………………………………………………………………………………
004EF734   |.  E8 03FFFFFF call 12_.004EF63C           輸入碼的轉換
就這樣的 ,在記憶體中把:
00B1E738  31 32 33 34 35 36 37 38   12345678
00B1E740  39 30 31 32 33 34 35 36   90123456
00B1E748  31 32 33 34 35 36 37 38   12345678
00B1E750  39 30 31 32 33 34 35 36   90123456
轉換成:
00B1B8F8  12 34 56 78 90 12 34 56   4Vx?4V
00B1B900  12 34 56 78 90 12 34 56   4Vx?4V


計算過程:每次取輸入碼的兩位,計算出註冊碼的兩位
第一次的前兩位輸入碼與(固定值)07FE的07異或得到註冊碼的兩位
同時用前兩位輸入碼與(固定值)07FE相加,其值再與0B相乘,值加上0C代替原來的(固定值)07FE,用於下一次計算
第二次的兩位輸入碼再與上次得到的固定值異或,得到註冊碼的3與4位,同樣的方法計算5與6位的固定值
如此往復。

我是這樣的:如果自己手工一個一個計算太煩,反正是異或,它是這樣的A XOR B =C  則A XOR C =B
我就把原來記憶體中我的輸入碼改成我的機器碼,讓程式自己幫我計算出真正的註冊碼來,!!
但因為計算第2位後面的註冊碼是,要用到前面兩位輸入碼。所以,第1,2位註冊碼一定要正確
用32bit Calculator v1.7計算了第1、2位是36(31(1)XOR 07(第一次固定值)=36)
後面的輸入碼先不動,要一個一個改了
004EF757   |> /8B45 F8     /mov eax,dword ptr ss:[ebp-8]      
004EF75A   |. |8A4418 FF   |mov al,byte ptr ds:[eax+ebx-1]    
004EF75E   |. |0FB7D6      |movzx edx,si                      
004EF761   |. |C1EA 08     |shr edx,8                         
004EF764   |. |32C2        |xor al,dl                在此處在斷點每次停在此處時,把AL該成機器碼ACII碼
004EF766   |. |84C0        |test al,al               再走一步把計算出來的AL中的值替換我的輸入碼                       

004EF768   |. |75 1F       |jnz short 12_.004EF789
004EF76A   |. |8B45 FC     |mov eax,dword ptr ss:[ebp-4]
004EF76D   |. |E8 7658F1FF |call 12_.00404FE8
004EF772   |. |8B55 F8     |mov edx,dword ptr ss:[ebp-8]
004EF775   |. |8A541A FF   |mov dl,byte ptr ds:[edx+ebx-1]
004EF779   |. |885418 FF   |mov byte ptr ds:[eax+ebx-1],dl
004EF77D   |. |66:6BC6 0B  |imul ax,si,0B
004EF781   |. |66:83C0 0C  |add ax,0C
004EF785   |. |8BF0        |mov esi,eax
004EF787   |. |EB 30       |jmp short 12_.004EF7B9
004EF789   |> |8B45 FC     |mov eax,dword ptr ss:[ebp-4]
004EF78C   |. |E8 5758F1FF |call 12_.00404FE8                 
004EF791   |. |8B55 F8     |mov edx,dword ptr ss:[ebp-8]      
004EF794   |. |8A541A FF   |mov dl,byte ptr ds:[edx+ebx-1]    
004EF798   |. |0FB7CE      |movzx ecx,si                      
004EF79B   |. |C1E9 08     |shr ecx,8                         
004EF79E   |. |32D1        |xor dl,cl                         
004EF7A0   |. |885418 FF   |mov byte ptr ds:[eax+ebx-1],dl    
004EF7A4   |. |8B45 F8     |mov eax,dword ptr ss:[ebp-8]      
004EF7A7   |. |0FB64418 FF |movzx eax,byte ptr ds:[eax+ebx-1] 
004EF7AC   |. |66:03F0     |add si,ax                         
004EF7AF   |. |66:6BC6 0B  |imul ax,si,0B                     
004EF7B3   |. |66:83C0 0C  |add ax,0C
004EF7B7   |. |8BF0        |mov esi,eax                       
004EF7B9   |> |43          |inc ebx
004EF7BA   |. |4F          |dec edi
004EF7BB   |.^\75 9A       \jnz short 12_.004EF757

這樣每次在004EF764中斷,在004EF766修正我的輸入碼,這樣一個一個的修正我的輸入碼,直到全部結束
修正好了的輸入碼就是真正的註冊碼!!
計算時,它把輸入碼與,計算出來的偽註冊碼放在不同的地方,沒有覆蓋的,
因為計算後面的要用前面的輸入碼。
結束。

相關文章