注册算法的分析

找到个共享软件练练手,一下是我的分析,做个备份算啦


*******************************************************
输入用户名和密码,运行断在此处
00412C70   .  8B46 64       mov eax,dword ptr ds:[esi+0x64]          ;  24cD938   序列号
00412C73   .  8B4E 60       mov ecx,dword ptr ds:[esi+0x60]          ;  24DC8E8 用户名
00412C76   .  50            push eax
00412C77   .  51            push ecx
00412C78   .  C64424 18 01  mov byte ptr ss:[esp+0x18],0x1

00412C7D   .  E8 EEFCFFFF   call Ahead_DV.00412970;根据下面代码可以看出这个是验证函数  

00412C82   .  83C4 08       add esp,0x8
00412C85   .  85C0          test eax,eax
00412C87   .  75 15         jnz short Ahead_DV.00412C9E
00412C89   .  6A 40         push 0x40
00412C8B   .  68 640D4D00   push Ahead.004D0D64                   ;  ASCII "Sorry"
**********************************************************************************
跟进出那个验证函数看看到底是什么逻辑吧
00412970  /$  53            push ebx
00412971  |.  55            push ebp
00412972  |.  8B6C24 0C     mov ebp,dword ptr ss:[esp+0xC]   ;  UserName地址赋给ebp

00412976  |.  56            push esi
00412977  |.  57            push edi
00412978  |.  BE CC1F4F00   mov esi,Ahead_DV.004F1FCC

0041297D  |.  8BC5          mov eax,ebp                       ;把UserName地址装载到eax
----------------------------------------------------------------------------
0041297F  |>  8A10          /mov dl,byte ptr ds:[eax]         ;  UserName[0]
00412981  |.  8A1E          |mov bl,byte ptr ds:[esi]          ;  ds[esi]此处是0
00412983  |.  8ACA          |mov cl,dl
00412985  |.  3AD3          |cmp dl,bl
00412987  |.  75 1E         |jnz short Ahead_DV.004129A7    ;  判断用户名是否为空
---------------------------------------------------------------------------------------
00412989  |.  84C9          |test cl,cl                     ;  根据下面的逻辑能验证上面的说的情况
0041298B  |.  74 16         |je short Ahead_DV.004129A3
0041298D  |.  8A50 01       |mov dl,byte ptr ds:[eax+0x1]
00412990  |.  8A5E 01       |mov bl,byte ptr ds:[esi+0x1]
00412993  |.  8ACA          |mov cl,dl
00412995  |.  3AD3          |cmp dl,bl
00412997  |.  75 0E         |jnz short Ahead_DV.004129A7
00412999  |.  83C0 02       |add eax,0x2
0041299C  |.  83C6 02       |add esi,0x2
0041299F  |.  84C9          |test cl,cl
004129A1  |.^ 75 DC         \jnz short Ahead_DV.0041297F
004129A3  |>  33C0          xor eax,eax
004129A5  |.  EB 05         jmp short Ahead_DV.004129AC

---------------------------------------
004129A7  |>  1BC0          sbb eax,eax                  ;判断用户名后跳到此处
004129A9  |.  83D8 FF       sbb eax,-0x1
004129AC  |>  85C0          test eax,eax                     eax=1  eax&eax不为0
004129AE  |.  74 51         je short Ahead_DV.00412A01  ;显然此处一定不会跳转
-----------------------------------------------------------
004129B0  |.  8B7C24 18     mov edi,dword ptr ss:[esp+0x18]          ;  序列号
004129B4  |.  BE CC1F4F00   mov esi,Ahead_DV.004F1FCC
004129B9  |.  8BC7          mov eax,edi
004129BB  |>  8A10          /mov dl,byte ptr ds:[eax]
004129BD  |.  8A1E          |mov bl,byte ptr ds:[esi]
004129BF  |.  8ACA          |mov cl,dl
004129C1  |.  3AD3          |cmp dl,bl                               ;  判断序列号是否为空
004129C3  |.  75 1E         |jnz short Ahead_DV.004129E3
---------------------------------------------------------------------------------------
004129C5  |.  84C9          |test cl,cl
004129C7  |.  74 16         |je short Ahead_DV.004129DF
004129C9  |.  8A50 01       |mov dl,byte ptr ds:[eax+0x1]
004129CC  |.  8A5E 01       |mov bl,byte ptr ds:[esi+0x1]
004129CF  |.  8ACA          |mov cl,dl
004129D1  |.  3AD3          |cmp dl,bl
004129D3  |.  75 0E         |jnz short Ahead_DV.004129E3
004129D5  |.  83C0 02       |add eax,0x2
004129D8  |.  83C6 02       |add esi,0x2
004129DB  |.  84C9          |test cl,cl
004129DD  |.^ 75 DC         \jnz short Ahead_DV.004129BB
004129DF  |>  33C0          xor eax,eax
004129E1  |.  EB 05         jmp short Ahead_DV.004129E8
------------------------------------------------------------------------
004129E3  |>  1BC0          sbb eax,eax                 ;序列号不为空跳到此处
004129E5  |.  83D8 FF       sbb eax,-0x1
004129E8  |>  85C0          test eax,eax             ;和上面一样此处不会跳转
004129EA  |.  74 15         je short Ahead_DV.00412A01
----------------------------------------------------------
004129EC  |.  57            push edi                                 ;  序列号地址
004129ED  |.  55            push ebp                                 ;  用户名地址
004129EE  |.  E8 4DFDFFFF   call Ahead_DV.00412740        ;根据下面的逻辑可以看出此函数
只是验证用户名和序列是否为空,加密代码在此函数中
-------------------------------------------------------------------------------
004129F3  |.  83C4 08       add esp,0x8
004129F6  |.  F7D8          neg eax
004129F8  |.  5F            pop edi
004129F9  |.  5E            pop esi
004129FA  |.  1BC0          sbb eax,eax
004129FC  |.  5D            pop ebp
004129FD  |.  F7D8          neg eax
004129FF  |.  5B            pop ebx
00412A00  |.  C3            retn
00412A01  |>  5F            pop edi
00412A02  |.  5E            pop esi
00412A03  |.  5D            pop ebp
00412A04  |.  33C0          xor eax,eax
00412A06  |.  5B            pop ebx
00412A07  \.  C3            retn
**************************************************************************************
验证完用户名和序列号 我们跟进这个函数,看看是什么逻辑
004D0C48  61 43 62 71 63 69 64 48  aCbqcidH
004D0C50  65 53 66 58 67 4D 68 6B  eSfXgMhk
004D0C58  69 45 6A 56 6B 5A 6C 65  iEjVkZle
004D0C60  6D 52 6E 79 6F 42 70 4B  mRnyoBpK
004D0C68  71 64 72 54 73 41 74 46  qdrTsAtF
004D0C70  75 57 76 6C 77 6A 78 44  uWvlwjxD
004D0C78  79 49 7A 50 41 7A 42 78  yIzPAzBx
004D0C80  43 70 44 4F 45 6B 46 67  CpDOEkFg
004D0C88  47 59 48 6D 49 74 4A 61  GYHmItJa
004D0C90  4B 72 4C 51 4D 6E 4E 73  KrLQMnNs
004D0C98  4F 75 50 55 51 47 52 4A  OuPUQGRJ
004D0CA0  53 4C 54 4E 55 62 56 63  SLTNUbVc
004D0CA8  57 66 58 68 59 6F 5A 77  WfXhYoZw
004D0CB0  5A 51 59                 ZQY

地址常量  下面会用到
---------------------------------------------------------------------------------
00412740  /$  6A FF         push -0x1
00412742  |.  68 F0AB4900   push Ahead_DV.0049ABF0                           ;  SE 处理程序安装
00412747  |.  64:A1 0000000>mov eax,dword ptr fs:[0]
0041274D  |.  50            push eax
0041274E  |.  64:8925 00000>mov dword ptr fs:[0],esp
-------------------------------------------------------------------------------------------------
00412755  |.  83EC 14       sub esp,0x14
00412758  |.  8B4424 24     mov eax,dword ptr ss:[esp+0x24]                  ;  eax=用户名地址

0041275C  |.  53            push ebx
0041275D  |.  55            push ebp
0041275E  |.  56            push esi
0041275F  |.  57            push edi
00412760  |.  50            push eax

00412761  |.  8D4C24 18     lea ecx,dword ptr ss:[esp+0x18]
00412765  |.  E8 AE560800   call <jmp.&MFC42.#CString::CString_537>          ;删除用户名的 换行符,空格,制表符

0041276A  |.  8D4C24 14     lea ecx,dword ptr ss:[esp+0x14]
0041276E  |.  C74424 2C 000>mov dword ptr ss:[esp+0x2C],0x0                  ;  removing new line, space, and tab characters.
00412776  |.  E8 67590800   call <jmp.&MFC42.#CString::TrimLeft_6282

0041277B  |.  8D4C24 14     lea ecx,dword ptr ss:[esp+0x14]
0041277F  |.  E8 58590800   call <jmp.&MFC42.#CString::TrimRight_6283>

00412784  |.  6A 20         push 0x20
00412786  |.  8D4C24 18     lea ecx,dword ptr ss:[esp+0x18]
0041278A  |.  E8 35560800   call <jmp.&MFC42.#CString::GetBuffer_2915>
-------------------------------------------------------------------------------------
0041278F  |.  8B4C24 38     mov ecx,dword ptr ss:[esp+0x38]                  ;  ecx=序列号地址
00412793  |.  8BD8          mov ebx,eax                                      ;  ebx=用户名地址
00412795  |.  51            push ecx
00412796  |.  8D4C24 14     lea ecx,dword ptr ss:[esp+0x14]
0041279A  |.  E8 79560800   call <jmp.&MFC42.#CString::CString_537>
0041279F  |.  8D4C24 10     lea ecx,dword ptr ss:[esp+0x10]
004127A3  |.  C64424 2C 01  mov byte ptr ss:[esp+0x2C],0x1
004127A8  |.  E8 35590800   call <jmp.&MFC42.#CString::TrimLeft_6282>		;删除序列号的 换行符,空格,制表符
004127AD  |.  8D4C24 10     lea ecx,dword ptr ss:[esp+0x10]
004127B1  |.  E8 26590800   call <jmp.&MFC42.#CString::TrimRight_6283>
004127B6  |.  6A 20         push 0x20
004127B8  |.  8D4C24 14     lea ecx,dword ptr ss:[esp+0x14]
004127BC  |.  E8 03560800   call <jmp.&MFC42.#CString::GetBuffer_2915>
004127C1  |.  8BD0          mov edx,eax                    ;  edx=序列号地址


---------------------------------------------------------------------------------------------------
004127C3  |.  83CE FF       or esi,-0x1
004127C6  |.  8BFA          mov edi,edx          ;  edi=序列号地址
004127C8  |.  8BCE          mov ecx,esi
004127CA  |.  33C0          xor eax,eax
004127CC  |.  895424 20     mov dword ptr ss:[esp+0x20],edx
004127D0  |.  F2:AE         repne scas byte ptr es:[edi]
004127D2  |.  F7D1          not ecx
004127D4  |.  49            dec ecx              ;  序列号长度
------------------------------------------------------
004127D5  |.  8BFB          mov edi,ebx            ;  edi=用户名地址
004127D7  |.  8BE9          mov ebp,ecx           ;  ebp=序列号长度
004127D9  |.  8BCE          mov ecx,esi
004127DB  |.  F2:AE         repne scas byte ptr es:[edi]
004127DD  |.  F7D1          not ecx
004127DF  |.  49            dec ecx             ;  用户名长度
004127E0  |.  3BCD          cmp ecx,ebp                                ;  用户名长度和序列号长度 比较
004127E2  |.  0F87 54010000 ja Ahead_DV.0041293C                ;  根据41293c处代码看出  正确的序列号len(序列号)>=len(用户名)
-----------------------------------------------------------------------------------------



004127E8  |.  8BFB          mov edi,ebx                                      ;  edi=用户名地址
004127EA  |.  8BCE          mov ecx,esi
004127EC  |.  F2:AE         repne scas byte ptr es:[edi]
004127EE  |.  F7D1          not ecx
004127F0  |.  49            dec ecx                                          ;  判断用户名是否为0
004127F1  |.  0F84 45010000 je Ahead_DV.0041293C

--------------------------------------------------------------
004127F7  |.  8BFA          mov edi,edx										; 序列号地址
004127F9  |.  8BCE          mov ecx,esi
004127FB  |.  F2:AE         repne scas byte ptr es:[edi]
004127FD  |.  F7D1          not ecx
004127FF  |.  49            dec ecx
00412800  |.  0F84 36010000 je Ahead_DV.0041293C                             ;  判断序列号长度是否为0
--------------------------------------------------------------


00412806  |.  894424 38     mov dword ptr ss:[esp+0x38],eax                  ;  [esp+0x38]=序列号地址
0041280A  |>  8B5424 38     /mov edx,dword ptr ss:[esp+0x38]
0041280E  |.  8D4C24 34     |lea ecx,dword ptr ss:[esp+0x34]
00412812  |.  8A82 B00C4D00 |mov al,byte ptr ds:[edx+0x4D0CB0]               ;  此处地址常量    ZQY.
00412818  |.  884424 18     |mov byte ptr ss:[esp+0x18],al
0041281C  |.  E8 19550800   |call <jmp.&MFC42.#CString::CString_540>

00412821  |.  8BFB          |mov edi,ebx
00412823  |.  83C9 FF       |or ecx,-0x1
00412826  |.  33C0          |xor eax,eax
00412828  |.  33ED          |xor ebp,ebp
0041282A  |.  F2:AE         |repne scas byte ptr es:[edi]
0041282C  |.  F7D1          |not ecx
0041282E  |.  49            |dec ecx                                         ;  用户名长度


0041282F  |.  C64424 2C 02  |mov byte ptr ss:[esp+0x2C],0x2
00412834  |.  74 4B         |je short Ahead_DV.00412881

此处是个循环
---------------------------------------------------------
00412836  |>  8A042B        |/mov al,byte ptr ds:[ebx+ebp]                   ;  UserName[ebp]
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
00412839  |.  33F6          ||xor esi,esi
0041283B  |>  3A0475 480C4D>||/cmp al,byte ptr ds:[esi*2+0x4D0C48]         esi为循环计数,在常量里找到用户名字符出现的位置
00412842  |.  74 08         |||je short Ahead_DV.0041284C
00412844  |.  46            |||inc esi
00412845  |.  83FE 34       |||cmp esi,0x34
00412848  |.^ 7C F1         ||\jl short Ahead_DV.0041283B
0x4D0C48 是个字符常量  上面我以列出



0041284A  |.  EB 11         ||jmp short Ahead_DV.0041285D              ; 此处代码为用户名的字符没有在常量里找到字符后此句代码

------------------------------------------------------------
0041284C  |>  8A0C75 490C4D>||mov cl,byte ptr ds:[esi*2+0x4D0C49]  ;这个常量地址和0x4D0C48 多1,可想而知cl取用户名出现位置的后一字符   
00412853  |.  51            ||push ecx
00412854  |.  8D4C24 38     ||lea ecx,dword ptr ss:[esp+0x38]                ;  用户名加密后的字符缓冲区 cl放到此处
00412858  |.  E8 79580800   ||call <jmp.&MFC42.#CString::operator+=_940>

------------------------------------------------------------------------------

这部分逻辑用c语言表示
c语言代码为 
char* p=0x4d0c48;
int i=0;
char u=UserName[ebp]
while(i<0x34)
{
	if(p[2*i]==u)
		break;
	i++;
}
CString encrypKey;
key=p[2*i+1]
encryKey+=key;

》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

0041285D  |>  83FE 34       ||cmp esi,0x34 					;if语句
00412860  |.  75 0E         ||jnz short Ahead_DV.00412870
if(esi==0x34)							显然此处用户名已在字符常量出现,不会执行此处代码,if不成立
{

00412862  |.  8B5424 18     ||mov edx,dword ptr ss:[esp+0x18]
00412866  |.  8D4C24 34     ||lea ecx,dword ptr ss:[esp+0x34]
0041286A  |.  52            ||push edx
0041286B  |.  E8 66580800   ||call <jmp.&MFC42.#CString::operator+=_940>
}

00412870  |>  8BFB          ||mov edi,ebx                                    ;  edi=用户名地址
00412872  |.  83C9 FF       ||or ecx,-0x1
00412875  |.  33C0          ||xor eax,eax
00412877  |.  45            ||inc ebp
00412878  |.  F2:AE         ||repne scas byte ptr es:[edi]
0041287A  |.  F7D1          ||not ecx
0041287C  |.  49            ||dec ecx                                        ;  用户名长度

0041287D  |.  3BE9          ||cmp ebp,ecx                                    ;  ebp为循环索引
0041287F  |.^ 72 B5         |\jb short Ahead_DV.00412836



循环加密后的生成的key为

即 encrypKey=”bASTsCRS“

堆栈 ss:[0018ECFC]=024CDB68, (ASCII "bASTsCRS")


继续分析  猜测 此密钥有可能和序列号比较,也有可能再经过加密和序列号比较,那就探个究竟吧!
--------------------------------------------------------------------------------
00412881  |>  8B4424 34     |mov eax,dword ptr ss:[esp+0x34]    eax=key的地址
00412885  |.  8B48 F8       |mov ecx,dword ptr ds:[eax-0x8]		ecx= key的长度

00412888  |.  83F9 10       |cmp ecx,0x10
0041288B  |.  7D 3A         |jge short Ahead_DV.004128C7		ecx>=0x10跳走  此key长度为8继续执行

0041288D  |.  8BC1          |mov eax,ecx		;eax=len(key)
0041288F  |.  B9 10000000   |mov ecx,0x10      
00412894  |.  2BC8          |sub ecx,eax        ;ecx=0x10-len(key)

00412896  |.  8D5424 1C     |lea edx,dword ptr ss:[esp+0x1C]
0041289A  |.  51            |push ecx                        ;8
0041289B  |.  52            |push edx  ;OD此处是序列地址
0041289C  |.  B9 BCF45000   |mov ecx,Ahead_DV.0050F4BC        新的CSTRING对象,到缓冲区看到字符常量为

024CD848  48 4C 57 73 43 62 4D 45  HLWsCbME
024CD850  72 70 41 51 4F 58 57 4B  rpAQOXWK
024CD858  00                       .

004128A1  |.  E8 2A580800   |call <jmp.&MFC42.#CString::Left_4129>

024CDBB8  48 4C 57 73 43 62 4D 45  HLWsCbME

004128A6  |.  50            |push eax    eax=024DBB8

004128A7  |.  8D4C24 38     |lea ecx,dword ptr ss:[esp+0x38]
004128AB  |.  C64424 30 03  |mov byte ptr ss:[esp+0x30],0x3
004128B0  |.  E8 4B550800   |call <jmp.&MFC42.#CString::operator+=_939>
004128B5  |.  8D4C24 1C     |lea ecx,dword ptr ss:[esp+0x1C]
004128B9  |.  C64424 2C 02  |mov byte ptr ss:[esp+0x2C],0x2
004128BE  |.  E8 6F530800   |call <jmp.&MFC42.#CString::~CString_800>
004128C3  |.  8B4424 34     |mov eax,dword ptr ss:[esp+0x34]
字符连接
”bASTsCRS“+“HLWsCbME”


经过以上分析 ,这几句代码意思是  生成的key 是否为16 个  不够就在024CD848地址常量里取出余下字符,知道key够16。
哈哈下面我终于看到带有cmp这个函数胜利就在眼前。
-----------------------------------------------------------------------------------
004128C7  |>  8B4C24 20     |mov ecx,dword ptr ss:[esp+0x20];key
004128CB  |.  51            |push ecx                                        ; /s2  key
004128CC  |.  50            |push eax                                        ; |s1  序列号
004128CD  |.  FF15 34D94900 |call dword ptr ds:[<&MSVCRT._mbscmp>]           ; \_mbscmp  key 和序列比较
004128D3  |.  83C4 08       |add esp,0x8

004128D6  |.  8D4C24 34     |lea ecx,dword ptr ss:[esp+0x34]
004128DA  |.  85C0          |test eax,eax        相等eax=0
004128DC  |.  C64424 2C 01  |mov byte ptr ss:[esp+0x2C],0x1
004128E1  |.  74 1B         |je short Ahead_DV.004128FE

004128E3  |.  33F6          |xor esi,esi
004128E5  |.  E8 48530800   |call <jmp.&MFC42.#CString::~CString_800>
004128EA  |.  8B4424 38     |mov eax,dword ptr ss:[esp+0x38]
004128EE  |.  40            |inc eax
004128EF  |.  83F8 03       |cmp eax,0x3
004128F2  |.  894424 38     |mov dword ptr ss:[esp+0x38],eax
004128F6  |.^ 0F8C 0EFFFFFF \jl Ahead_DV.0041280A
004128FC  |.  EB 0A         jmp short Ahead_DV.00412908


004128FE  |>  BE 01000000   mov esi,0x1      ;标志位

00412903  |.  E8 2A530800   call <jmp.&MFC42.#CString::~CString_800>
00412908  |>  8D4C24 10     lea ecx,dword ptr ss:[esp+0x10]
0041290C  |.  C64424 2C 00  mov byte ptr ss:[esp+0x2C],0x0
00412911  |.  E8 1C530800   call <jmp.&MFC42.#CString::~CString_800>
00412916  |.  8D4C24 14     lea ecx,dword ptr ss:[esp+0x14]
0041291A  |.  C74424 2C FFF>mov dword ptr ss:[esp+0x2C],-0x1
00412922  |.  E8 0B530800   call <jmp.&MFC42.#CString::~CString_800>
00412927  |.  8BC6          mov eax,esi   赋给eax

00412929  |.  5F            pop edi
0041292A  |.  5E            pop esi
0041292B  |.  5D            pop ebp
0041292C  |.  5B            pop ebx
0041292D  |.  8B4C24 14     mov ecx,dword ptr ss:[esp+0x14]
00412931  |.  64:890D 00000>mov dword ptr fs:[0],ecx
00412938  |.  83C4 20       add esp,0x20
0041293B  |.  C3            retn  

到此分析结束  加密比较简单,总结:
在分析的过程应保持数据的敏感性。
下面是我还原总的代码:
#include<iostream>
#include<string>
using namespace std;
char p[]="aCbqcidHeSfXgMhkiEjVkZlemRnyoBpKqdrTsAtFuWvlwjxDyIzPAzBxCpDOEkFgGYHmItJaKrLQMnNsOuPUQGRJSLTNUbVcWfXhYoZw";
char q[]="HLWsCbMErpAQOXWK";
void Reducekey(char*user,char*psd)
{
	string key;
	int lenOfUser=strlen(user);
	for(int j=0;j<lenOfUser;j++)
	{
		int i=0;
		while(i<0x34)
		{
			if(p[2*i]==user[j])
				break;
			i++;
		}
		key+=p[2*i+1];
	}
	int lenOfKey=key.length();
	if(lenOfKey<=0x10)
	{
		int sub=0x10-lenOfKey;
		int i=0;
		while(i<sub)
		{
			key+=q[i++];
		}
	}
	cout<<key.c_str()<<endl;

}
int _tmain(int argc, _TCHAR* argv[])
{
	

	Reducekey("UserName","");
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值