datochan 发表于 2009-2-12 23:13

赚取权限第二贴之某打字练习软件的注册算法分析笔记

帖第二篇了,看现在的破解业界,几乎人人都是高手,正如MJ说的,一个技术,专门研究一个月就是牛人了,我等菜菜,真的不知道我的这个破文拿出来是不是会被笑话~
为了摆脱新人的现状,我豁出去了,希望各位大大不要笑话我~~~
上次帖的是JAVA的,这次来个VB的吧~~~,这个是我第一次分析VB时的文章,当时费了好大的劲,但是收获不小,希望各位分析过VB程序的大大指点,没有分析过VB的朋友借鉴……
正文如下:
【文章标题】: 某打字练习软件的注册算法分析笔记
【软件介绍】: 用来练习打字的软件!
【作者声明】:
    从来没有想过我能有能力用OD来分析某个软件的算法,因为我以前基本上都是爆破,或者用OD跟出注册码。在听了很多人对我的鼓励之后,我决定:选一个比较容易的软柿子来捏一下,自己分析一下算法,当作是对自己的锻炼吧!由于是第一次分析,错误之处再所难免,望各位大虾指教!!!
--------------------------------------------------------------------------------
【详细过程】:
脱壳不说了,至于找关键跳的方法,我忘记哪个“老大”教导我们说的:“VB程序找比较函数”,所以在_vbaStrCmp函数上下断点,应该是可以断到关键比较上的!


代码:005C9A38   .FF15 8C124000 call    dword ptr [<&msvbvm60.__vbaStrCo>;msvbvm60.__vbaStrCopy
005C9A3E   .83EC 10       sub   esp, 10
005C9A41   .B9 08000000   mov   ecx, 8
005C9A46   .8BD4          mov   edx, esp
005C9A48   .898D 50FFFFFF mov   dword ptr , ecx
005C9A4E   .8B1D C8124000 mov   ebx, dword ptr [<&msvbvm60.rtcGe>;msvbvm60.rtcGetSetting
005C9A54   .B8 D0EA4100   mov   eax, 0041EAD0                  ;UNICODE "dlei"
005C9A59   .890A          mov   dword ptr , ecx
005C9A5B   .8B8D 54FFFFFF mov   ecx, dword ptr
005C9A61   .8985 58FFFFFF mov   dword ptr , eax
005C9A67   .68 C0EA4100   push    0041EAC0                         ; /szKey = "Name"
005C9A6C   .894A 04       mov   dword ptr , ecx         ; |
005C9A6F   .68 B0EA4100   push    0041EAB0                         ; |Section = "login"
005C9A74   .68 A0EA4100   push    0041EAA0                         ; |AppName = "运?,B8,"如",B7,"?"
005C9A79   .8942 08       mov   dword ptr , eax         ; |
005C9A7C   .8B85 5CFFFFFF mov   eax, dword ptr           ; |
005C9A82   .8942 0C       mov   dword ptr , eax         ; |
005C9A85   .FFD3          call    ebx                              ; \rtcGetSetting
005C9A87   .8B3D 24134000 mov   edi, dword ptr [<&msvbvm60.__vba>;得到了用户名
005C9A8D   .8BD0          mov   edx, eax
005C9A8F   .8D4D D4       lea   ecx, dword ptr
005C9A92   .FFD7          call    edi                              ;<&msvbvm60.__vbaStrMove>
005C9A94   .8D4D D4       lea   ecx, dword ptr
005C9A97   .8D55 D8       lea   edx, dword ptr
005C9A9A   .51            push    ecx
005C9A9B   .52            push    edx
005C9A9C   .E8 2F900200   call    005F2AD0                         ;这里得到了真码~`
005C9AA1   .8BD0          mov   edx, eax
005C9AA3   .8D4D E4       lea   ecx, dword ptr
005C9AA6   .FFD7          call    edi
005C9AA8   .8D4D D4       lea   ecx, dword ptr
005C9AAB   .FF15 64134000 call    dword ptr [<&msvbvm60.__vbaFreeS>;msvbvm60.__vbaFreeStr
005C9AB1   .83EC 10       sub   esp, 10
005C9AB4   .B9 08000000   mov   ecx, 8
005C9AB9   .8BD4          mov   edx, esp
005C9ABB   .898D 50FFFFFF mov   dword ptr , ecx
005C9AC1   .B8 ECEA4100   mov   eax, 0041EAEC                  ;UNICODE "1a2b3c"
005C9AC6   .68 E0EA4100   push    0041EAE0                         ;UNICODE "id"
005C9ACB   .890A          mov   dword ptr , ecx
005C9ACD   .8B8D 54FFFFFF mov   ecx, dword ptr
005C9AD3   .8985 58FFFFFF mov   dword ptr , eax
005C9AD9   .68 B0EA4100   push    0041EAB0                         ;UNICODE "login"
005C9ADE   .894A 04       mov   dword ptr , ecx
005C9AE1   .68 A0EA4100   push    0041EAA0
005C9AE6   .8942 08       mov   dword ptr , eax
005C9AE9   .8B85 5CFFFFFF mov   eax, dword ptr
005C9AEF   .8942 0C       mov   dword ptr , eax
005C9AF2   .FFD3          call    ebx                              ;得到了我们输入的注册码,我们F7跟进去!~
005C9AF4   .8BD0          mov   edx, eax
005C9AF6   .8D4D E0       lea   ecx, dword ptr
005C9AF9   .FFD7          call    edi
005C9AFB   .8B4D E0       mov   ecx, dword ptr
005C9AFE   .51            push    ecx                              ; /String
005C9AFF   .FF15 30104000 call    dword ptr [<&msvbvm60.__vbaLenBs>; \__vbaLenBstr
005C9B05   .8BC8          mov   ecx, eax
005C9B07   .FF15 80114000 call    dword ptr [<&msvbvm60.__vbaI2I4>>;msvbvm60.__vbaI2I4
005C9B0D   .8B1D 40114000 mov   ebx, dword ptr [<&msvbvm60.rtcMi>;msvbvm60.rtcMidCharVar
005C9B13   .8985 F0FEFFFF mov   dword ptr , eax
005C9B19   .B8 01000000   mov   eax, 1
005C9B1E   .8945 E8       mov   dword ptr , eax
005C9B21   >66:3B85 F0FEF>cmp   ax, word ptr          ;这个循环在处理我们输入的注册码
005C9B28   .0F8F A0010000 jg      005C9CCE
005C9B2E   .0FBFF8      movsx   edi, ax
005C9B31   .8D55 E0       lea   edx, dword ptr
005C9B34   .8D45 C0       lea   eax, dword ptr
005C9B37   .8995 58FFFFFF mov   dword ptr , edx
005C9B3D   .50            push    eax
005C9B3E   .8D8D 50FFFFFF lea   ecx, dword ptr
005C9B44   .57            push    edi
005C9B45   .8D55 B0       lea   edx, dword ptr
005C9B48   .51            push    ecx
005C9B49   .52            push    edx
005C9B4A   .C745 C8 01000>mov   dword ptr , 1
005C9B51   .C745 C0 02000>mov   dword ptr , 2
005C9B58   .C785 50FFFFFF>mov   dword ptr , 4008
005C9B62   .FFD3          call    ebx
005C9B64   .8D45 E0       lea   eax, dword ptr
005C9B67   .8D4D 90       lea   ecx, dword ptr
005C9B6A   .8985 28FFFFFF mov   dword ptr , eax
005C9B70   .51            push    ecx
005C9B71   .8D95 20FFFFFF lea   edx, dword ptr
005C9B77   .57            push    edi
005C9B78   .8D45 80       lea   eax, dword ptr
005C9B7B   .52            push    edx
005C9B7C   .50            push    eax
005C9B7D   .89B5 38FFFFFF mov   dword ptr , esi
005C9B83   .C785 30FFFFFF>mov   dword ptr , 8002
005C9B8D   .C745 98 01000>mov   dword ptr , 1
005C9B94   .C745 90 02000>mov   dword ptr , 2
005C9B9B   .C785 20FFFFFF>mov   dword ptr , 4008
005C9BA5   .FFD3          call    ebx
005C9BA7   .8D4D B0       lea   ecx, dword ptr
005C9BAA   .8D95 30FFFFFF lea   edx, dword ptr
005C9BB0   .51            push    ecx
005C9BB1   .8D45 A0       lea   eax, dword ptr
005C9BB4   .52            push    edx
005C9BB5   .50            push    eax
005C9BB6   .C785 08FFFFFF>mov   dword ptr , 9
005C9BC0   .C785 00FFFFFF>mov   dword ptr , 8002
005C9BCA   .FF15 48114000 call    dword ptr [<&msvbvm60.__vbaVarCm>;msvbvm60.__vbaVarCmpGt
005C9BD0   .8D4D 80       lea   ecx, dword ptr
005C9BD3   .50            push    eax
005C9BD4   .8D95 00FFFFFF lea   edx, dword ptr
005C9BDA   .51            push    ecx
005C9BDB   .8D85 70FFFFFF lea   eax, dword ptr
005C9BE1   .52            push    edx
005C9BE2   .50            push    eax
005C9BE3   .FF15 9C124000 call    dword ptr [<&msvbvm60.__vbaVarCm>;msvbvm60.__vbaVarCmpLt
005C9BE9   .8D8D 60FFFFFF lea   ecx, dword ptr
005C9BEF   .50            push    eax
005C9BF0   .51            push    ecx
005C9BF1   .FF15 CC114000 call    dword ptr [<&msvbvm60.__vbaVarAn>;msvbvm60.__vbaVarAnd
005C9BF7   .50            push    eax
005C9BF8   .FF15 2C114000 call    dword ptr [<&msvbvm60.__vbaBoolV>;msvbvm60.__vbaBoolVarNull
005C9BFE   .66:8985 FCFEF>mov   word ptr , ax
005C9C05   .8D55 80       lea   edx, dword ptr
005C9C08   .8D45 90       lea   eax, dword ptr
005C9C0B   .52            push    edx
005C9C0C   .8D4D B0       lea   ecx, dword ptr
005C9C0F   .50            push    eax
005C9C10   .8D55 C0       lea   edx, dword ptr
005C9C13   .51            push    ecx
005C9C14   .52            push    edx
005C9C15   .6A 04         push    4
005C9C17   .FF15 44104000 call    dword ptr [<&msvbvm60.__vbaFreeV>;msvbvm60.__vbaFreeVarList
005C9C1D   .83C4 14       add   esp, 14
005C9C20   .66:39B5 FCFEF>cmp   word ptr , si
005C9C27   .0F84 84000000 je      005C9CB1
005C9C2D   .8B45 DC       mov   eax, dword ptr
005C9C30   .8D4D E0       lea   ecx, dword ptr
005C9C33   .8D55 C0       lea   edx, dword ptr
005C9C36   .8985 38FFFFFF mov   dword ptr , eax
005C9C3C   .898D 58FFFFFF mov   dword ptr , ecx
005C9C42   .52            push    edx
005C9C43   .8D85 50FFFFFF lea   eax, dword ptr
005C9C49   .57            push    edi
005C9C4A   .8D4D B0       lea   ecx, dword ptr
005C9C4D   .50            push    eax
005C9C4E   .51            push    ecx
005C9C4F   .C785 30FFFFFF>mov   dword ptr , 8
005C9C59   .C745 C8 01000>mov   dword ptr , 1
005C9C60   .C745 C0 02000>mov   dword ptr , 2
005C9C67   .C785 50FFFFFF>mov   dword ptr , 4008
005C9C71   .FFD3          call    ebx
005C9C73   .8D95 30FFFFFF lea   edx, dword ptr
005C9C79   .8D45 B0       lea   eax, dword ptr
005C9C7C   .52            push    edx
005C9C7D   .8D4D A0       lea   ecx, dword ptr
005C9C80   .50            push    eax
005C9C81   .51            push    ecx
005C9C82   .FF15 38124000 call    dword ptr [<&msvbvm60.__vbaVarCa>;msvbvm60.__vbaVarCat
005C9C88   .50            push    eax
005C9C89   .FF15 2C104000 call    dword ptr [<&msvbvm60.__vbaStrVa>;msvbvm60.__vbaStrVarMove
005C9C8F   .8BD0          mov   edx, eax
005C9C91   .8D4D DC       lea   ecx, dword ptr
005C9C94   .FF15 24134000 call    dword ptr [<&msvbvm60.__vbaStrMo>;msvbvm60.__vbaStrMove
005C9C9A   .8D55 A0       lea   edx, dword ptr
005C9C9D   .8D45 B0       lea   eax, dword ptr
005C9CA0   .52            push    edx
005C9CA1   .8D4D C0       lea   ecx, dword ptr
005C9CA4   .50            push    eax
005C9CA5   .51            push    ecx
005C9CA6   .6A 03         push    3
005C9CA8   .FF15 44104000 call    dword ptr [<&msvbvm60.__vbaFreeV>;msvbvm60.__vbaFreeVarList
005C9CAE   .83C4 10       add   esp, 10
005C9CB1   >8B3D 24134000 mov   edi, dword ptr [<&msvbvm60.__vba>;msvbvm60.__vbaStrMove
005C9CB7   .B8 01000000   mov   eax, 1
005C9CBC   .66:0345 E8    add   ax, word ptr
005C9CC0   .0F80 2A010000 jo      005C9DF0
005C9CC6   .8945 E8       mov   dword ptr , eax
005C9CC9   .^ E9 53FEFFFF   jmp   005C9B21         ;循环结束。这个循环就是将我们输入的注册码中所有的字母,0,9,全部过滤掉!

      

005C9CCE   >8B55 DC       mov   edx, dword ptr           ;处理完以后的注册码
005C9CD1   .52            push    edx                              ; /String
005C9CD2   .FF15 F0114000 call    dword ptr [<&msvbvm60.rtcStrReve>; \将处理完以后的注册码,反序
005C9CD8   .8BD0          mov   edx, eax
005C9CDA   .8D4D DC       lea   ecx, dword ptr
005C9CDD   .FFD7          call    edi
005C9CDF   .8B45 E4       mov   eax, dword ptr           ;取出计算好的真码,由这里可以定位到005C9A9Ccall005F2AD0这个函数得到了真码!   
005C9CE2   .8B4D DC       mov   ecx, dword ptr           ;得到我们输入的并经过处理的注册码
005C9CE5   .50            push    eax
005C9CE6   .51            push    ecx
005C9CE7   .FF15 68114000 call    dword ptr [<&msvbvm60.__vbaStrCm>;开始比较
005C9CED   .85C0          test    eax, eax
005C9CEF   .74 33         je      short 005C9D24                   ;这里就是关键跳了~~~~

005C9CF1   .8B45 08       mov   eax, dword ptr
005C9CF4   .66:8935 3CF05>mov   word ptr , si
005C9CFB   .50            push    eax
005C9CFC   .8B10          mov   edx, dword ptr
005C9CFE   .FF92 1C050000 call    dword ptr
好了,到这里我们就可以定位到算法部分了,在005C9A9Ccall005F2AD0处F7,跟进去:005F2AD0   $55            push    ebp
005F2AD1   .8BEC          mov   ebp, esp
005F2AD3   .83EC 0C       sub   esp, 0C
005F2AD6   .68 662B4000   push    <jmp.&msvbvm60.__vbaExceptHandle>;SE 处理程序安装
005F2ADB   .64:A1 0000000>mov   eax, dword ptr fs:
005F2AE1   .50            push    eax


005F2B55   .FF15 30104000 call    dword ptr [<&msvbvm60.__vbaLenBs>; \__vbaLenBstr
005F2B5B   .8BC8          mov   ecx, eax                         ;得到用户名的长度
005F2B5D   .FF15 80114000 call    dword ptr [<&msvbvm60.__vbaI2I4>>;msvbvm60.__vbaI2I4
005F2B63   .8B1D 24134000 mov   ebx, dword ptr [<&msvbvm60.__vba>;msvbvm60.__vbaStrMove
005F2B69   .8B3D 44104000 mov   edi, dword ptr [<&msvbvm60.__vba>;msvbvm60.__vbaFreeVarList
005F2B6F   .66:2D 0100    sub   ax, 1                            ;这里开始第一次循环
005F2B73   .0F80 B3090000 jo      005F352C
005F2B79   .8985 E8FEFFFF mov   dword ptr , eax
005F2B7F   >8B55 DC       mov   edx, dword ptr       
005F2B82   .66:3BB5 E8FEF>cmp   si, word ptr
005F2B89   .52            push    edx
005F2B8A   .0F8F EC000000 jg      005F2C7C                         ;如果位数大于用户名的长度,则跳
005F2B90   .FF15 20104000 call    dword ptr [<&msvbvm60.__vbaStrI4>;msvbvm60.__vbaStrI4
005F2B96   .8BD0          mov   edx, eax
005F2B98   .8D4D C8       lea   ecx, dword ptr
005F2B9B   .FFD3          call    ebx
005F2B9D   .50            push    eax                              ; /String
005F2B9E   .FF15 F0114000 call    dword ptr [<&msvbvm60.rtcStrReve>; \字符串反序
005F2BA4   .8BD0          mov   edx, eax
005F2BA6   .8D4D C4       lea   ecx, dword ptr
005F2BA9   .FFD3          call    ebx
005F2BAB   .50            push    eax
005F2BAC   .FF15 90124000 call    dword ptr [<&msvbvm60.__vbaI4Str>;msvbvm60.__vbaI4Str
005F2BB2   .8945 DC       mov   dword ptr , eax
005F2BB5   .8D45 C4       lea   eax, dword ptr
005F2BB8   .8D4D C8       lea   ecx, dword ptr
005F2BBB   .50            push    eax
005F2BBC   .51            push    ecx
005F2BBD   .6A 02         push    2
005F2BBF   .FF15 98124000 call    dword ptr [<&msvbvm60.__vbaFreeS>;msvbvm60.__vbaFreeStrList
005F2BC5   .8B55 0C       mov   edx, dword ptr
005F2BC8   .66:8BCE       mov   cx, si
005F2BCB   .83C4 0C       add   esp, 0C
005F2BCE   .66:83C1 01    add   cx, 1
005F2BD2   .8995 4CFFFFFF mov   dword ptr , edx
005F2BD8   .8D45 B4       lea   eax, dword ptr
005F2BDB   .0F80 4B090000 jo      005F352C
005F2BE1   .0FBFD1      movsx   edx, cx
005F2BE4   .50            push    eax                              ; /Length8
005F2BE5   .8D85 44FFFFFF lea   eax, dword ptr           ; |
005F2BEB   .52            push    edx                              ; |Start
005F2BEC   .8D4D A4       lea   ecx, dword ptr           ; |
005F2BEF   .50            push    eax                              ; |dString8
005F2BF0   .51            push    ecx                              ; |RetBUFFER
005F2BF1   .C745 BC 01000>mov   dword ptr , 1            ; |
005F2BF8   .C745 B4 02000>mov   dword ptr , 2            ; |
005F2BFF   .C785 44FFFFFF>mov   dword ptr , 4008         ; |
005F2C09   .FF15 40114000 call    dword ptr [<&msvbvm60.rtcMidChar>; \rtcMidCharVar
005F2C0F   .8D55 A4       lea   edx, dword ptr
005F2C12   .8D45 C8       lea   eax, dword ptr
005F2C15   .52            push    edx                              ; /String8
005F2C16   .50            push    eax                              ; |ARG2
005F2C17   .FF15 2C124000 call    dword ptr [<&msvbvm60.__vbaStrVa>; \__vbaStrVarVal
005F2C1D   .50            push    eax                              ; /String
005F2C1E   .FF15 5C104000 call    dword ptr [<&msvbvm60.rtcAnsiVal>; \依次得到用户名每个字符的ASC
005F2C24   .8B4D DC       mov   ecx, dword ptr
005F2C27   .0FBFD0      movsx   edx, ax
005F2C2A   .2BCA          sub   ecx, edx
005F2C2C   .0F80 FA080000 jo      005F352C
005F2C32   .83C1 08       add   ecx, 8         ; +8
005F2C35   .0F80 F1080000 jo      005F352C
005F2C3B   .FF15 D8104000 call    dword ptr [<&msvbvm60.__vbaI4Abs>;msvbvm60.__vbaI4Abs
005F2C41   .8B55 DC       mov   edx, dword ptr
005F2C44   .8D4D C8       lea   ecx, dword ptr
005F2C47   .03C2          add   eax, edx
005F2C49   .0F80 DD080000 jo      005F352C
005F2C4F   .8945 DC       mov   dword ptr , eax       ;
005F2C52   .FF15 64134000 call    dword ptr [<&msvbvm60.__vbaFreeS>;msvbvm60.__vbaFreeStr
005F2C58   .8D45 A4       lea   eax, dword ptr
005F2C5B   .8D4D B4       lea   ecx, dword ptr
005F2C5E   .50            push    eax
005F2C5F   .51            push    ecx
005F2C60   .6A 02         push    2
005F2C62   .FFD7          call    edi
005F2C64   .B8 01000000   mov   eax, 1
005F2C69   .83C4 0C       add   esp, 0C
005F2C6C   .66:03C6       add   ax, si
005F2C6F   .0F80 B7080000 jo      005F352C
005F2C75   .8BF0          mov   esi, eax
005F2C77   .^ E9 03FFFFFF   jmp   005F2B7F
忽忽,这个循环终于看明白了,前后有三次差点就放弃……,幸好我有汇编指令速查手册,否则就凭我那汇编的破水平,还真的分析不下去了!这个循环就是处理用户名,可是我VC用的太差劲,我不知道VC里面用来将字符串反序的函数是什么,只有自己写了,这样上面的代码用C表示代码如下:CString CYzrfKEYGENDlg::StrReverse(char *str)//这个函数就是将字符串反序
{
CString mstr(str);
CString cstr;

for(int i = mstr.GetLength()-1; i >= 0; i--)
{
    cstr += mstr.GetAt(i);
}

return cstr;
}
void CYzrfKEYGENDlg::OnOK()
{
// TODO: Add extra validation here
UpdateData(TRUE);
int edx = 0;
int res = 0;
CString cstr;
for(int i=0; i < m_Name.GetLength();i++)
{
    char code;
    int asc = 0;

    itoa(res,code,10);
    cstr = StrReverse(code);
    edx = atoi(cstr);
    res = edx;

    asc = m_Name.GetAt(i);
    edx -= asc;
    edx +=8;
    edx = abs(edx);
    res += edx;   
}
cstr.Format("%d",res);//这里的cstr中就是循环的结果了~
MessageBox(cstr);
}
哎,第一个循环就用了我近10个小时(大部分时间都用来查汇编指令了,看来汇编急需饿补哦`~~~),真的不敢相信我会将这个程序分析完~~~,可是都费了这么多的时间了,现在放弃真的不甘心!!!
    等明天在继续分析第二个循环吧~~~
第二个循环如下:005F2C7C   > \FF15 20104000 call    dword ptr [<&msvbvm60.__vbaStrI4>]       ;msvbvm60.__vbaStrI4
005F2C82   .8BD0          mov   edx, eax                                 ;将循环处理的结果给EDX
005F2C84   .8D4D D4       lea   ecx, dword ptr
005F2C87   .FFD3          call    ebx
005F2C89   .8B75 08       mov   esi, dword ptr
005F2C8C   .8B06          mov   eax, dword ptr                      ;取出机器码
005F2C8E   .50            push    eax                                    ; /String
005F2C8F   .FF15 30104000 call    dword ptr [<&msvbvm60.__vbaLenBstr>]   ; \__vbaLenBstr
005F2C95   .8BC8          mov   ecx, eax                                 ;取机器码的长度
005F2C97   .83E9 01       sub   ecx, 1
005F2C9A   .0F80 8C080000 jo      005F352C
005F2CA0   .FF15 80114000 call    dword ptr [<&msvbvm60.__vbaI2I4>]      ;msvbvm60.__vbaI2I4
005F2CA6   .8985 E0FEFFFF mov   dword ptr , eax
005F2CAC   .C745 D8 01000>mov   dword ptr , 1
005F2CB3   >66:8B8D E0FEF>mov   cx, word ptr                    ;这里开始第二次循环
005F2CBA   .66:394D D8    cmp   word ptr , cx
005F2CBE   .0F8F 17010000 jg      005F2DDB
005F2CC4   .8B55 D4       mov   edx, dword ptr                   ;取出上个循环得到的字符串
005F2CC7   .52            push    edx                                    ; /String
005F2CC8   .FF15 30104000 call    dword ptr [<&msvbvm60.__vbaLenBstr>]   ; \__vbaLenBstr
005F2CCE   .8B4D E4       mov   ecx, dword ptr                   ;取它的长度
005F2CD1   .0FBFD1      movsx   edx, cx
005F2CD4   .3BD0          cmp   edx, eax
005F2CD6   .7C 09         jl      short 005F2CE1
005F2CD8   .C745 E4 01000>mov   dword ptr , 1
005F2CDF   .EB 0D         jmp   short 005F2CEE
005F2CE1   >66:83C1 01    add   cx, 1                                    ;计数器加1
005F2CE5   .0F80 41080000 jo      005F352C
005F2CEB   .894D E4       mov   dword ptr , ecx
005F2CEE   >0FBF45 D8   movsx   eax, word ptr
005F2CF2   .8D4D B4       lea   ecx, dword ptr
005F2CF5   .8D95 44FFFFFF lea   edx, dword ptr
005F2CFB   .51            push    ecx                                    ; /Length8
005F2CFC   .50            push    eax                                    ; |Start
005F2CFD   .8D45 A4       lea   eax, dword ptr                   ; |
005F2D00   .52            push    edx                                    ; |dString8
005F2D01   .50            push    eax                                    ; |上个循环中的结果
005F2D02   .C745 BC 01000>mov   dword ptr , 1                  ; |
005F2D09   .C745 B4 02000>mov   dword ptr , 2                  ; |
005F2D10   .89B5 4CFFFFFF mov   dword ptr , esi                  ; |
005F2D16   .C785 44FFFFFF>mov   dword ptr , 4008               ; |
005F2D20   .FF15 40114000 call    dword ptr [<&msvbvm60.rtcMidCharVar>]    ; \从上个循环的结果中依次取字符
005F2D26   .0FBF45 E4   movsx   eax, word ptr
005F2D2A   .8D4D DC       lea   ecx, dword ptr
005F2D2D   .8D55 94       lea   edx, dword ptr
005F2D30   .898D 2CFFFFFF mov   dword ptr , ecx
005F2D36   .52            push    edx                                    ; /Length8
005F2D37   .8D8D 24FFFFFF lea   ecx, dword ptr                   ; |
005F2D3D   .50            push    eax                                    ; |Start
005F2D3E   .8D55 84       lea   edx, dword ptr                   ; |
005F2D41   .51            push    ecx                                    ; |dString8
005F2D42   .52            push    edx                                    ; |RetBUFFER
005F2D43   .C745 9C 01000>mov   dword ptr , 1                  ; |
005F2D4A   .C745 94 02000>mov   dword ptr , 2                  ; |
005F2D51   .C785 24FFFFFF>mov   dword ptr , 4003               ; |
005F2D5B   .FF15 40114000 call    dword ptr [<&msvbvm60.rtcMidCharVar>]    ; \从机器码中依次取字符
005F2D61   .0FBF45 D8   movsx   eax, word ptr
005F2D65   .56            push    esi
005F2D66   .50            push    eax
005F2D67   .8D45 A4       lea   eax, dword ptr
005F2D6A   .6A 01         push    1
005F2D6C   .8D4D 84       lea   ecx, dword ptr
005F2D6F   .50            push    eax
005F2D70   .8D95 74FFFFFF lea   edx, dword ptr
005F2D76   .51            push    ecx
005F2D77   .52            push    edx
005F2D78   .FF15 B0104000 call    dword ptr [<&msvbvm60.__vbaVarXor>]      ;将上两个函数取出的的字符进行异或
005F2D7E   .50            push    eax
005F2D7F   .FF15 2C104000 call    dword ptr [<&msvbvm60.__vbaStrVarMove>];msvbvm60.__vbaStrVarMove
005F2D85   .8BD0          mov   edx, eax
005F2D87   .8D4D C8       lea   ecx, dword ptr
005F2D8A   .FFD3          call    ebx
005F2D8C   .50            push    eax
005F2D8D   .6A 00         push    0
005F2D8F   .FF15 5C134000 call    dword ptr [<&msvbvm60.__vbaMidStmtBstr>] ;msvbvm60.__vbaMidStmtBstr
005F2D95   .8D4D C8       lea   ecx, dword ptr
005F2D98   .FF15 64134000 call    dword ptr [<&msvbvm60.__vbaFreeStr>]   ;msvbvm60.__vbaFreeStr
005F2D9E   .8D45 84       lea   eax, dword ptr
005F2DA1   .8D4D A4       lea   ecx, dword ptr
005F2DA4   .50            push    eax
005F2DA5   .8D55 94       lea   edx, dword ptr
005F2DA8   .51            push    ecx
005F2DA9   .8D45 B4       lea   eax, dword ptr
005F2DAC   .52            push    edx
005F2DAD   .50            push    eax
005F2DAE   .6A 04         push    4
005F2DB0   .FFD7          call    edi
005F2DB2   .8B0E          mov   ecx, dword ptr
005F2DB4   .83C4 14       add   esp, 14
005F2DB7   .51            push    ecx                                    ; /String
005F2DB8   .FF15 F0114000 call    dword ptr [<&msvbvm60.rtcStrReverse>]    ; \将字符反序
005F2DBE   .8BD0          mov   edx, eax
005F2DC0   .8BCE          mov   ecx, esi
005F2DC2   .FFD3          call    ebx
005F2DC4   .B8 01000000   mov   eax, 1
005F2DC9   .66:0345 D8    add   ax, word ptr
005F2DCD   .0F80 59070000 jo      005F352C
005F2DD3   .8945 D8       mov   dword ptr , eax
005F2DD6   .^ E9 D8FEFFFF   jmp   005F2CB3                                 ;循环结束
我现在都开始后悔我怎么选择了一个VB程序呢?怎么我连系统的API函数的功能都看不明白啊,<&msvbvm60.rtcMidCharVar>这个函数,都知道它就是VB中的MID(),可是怎么一个取字符串的函数里没有字符串呢?全是什么4003,4008,函数返回的结果本来应该是某个字符串,可是OD返回的结果却是120008,这都是哪里跟哪里啊?

    终于,我经过饿补VB程序的分析方法、狂查看雪精华集。这段代码我也算熬过去了,很多时候真的需要我们有点毅力,不要轻易说放弃哈~~~~,这里谢谢MENGLONG大哥的《浅谈VB6逆向工程》系列文章,让我受益非浅,在这里膜拜一下~~~~~~~~~~~,至于我学到的东西,我贴到文章最后的经验总结中,都是写老生常谈的东西,但都是肺腑之言,希望能对跟我一样菜的朋友有所帮助!

    这段代码就是取出机器码,依次将上一个循环算出的字符串的第一个字符异或,然后在将得到的字符串反序,再进行第二个字符异或,依次类推,如下面:242245872125
    ↓3   =    2 xor 1
342245872125
    ↓反序
521278542243
    ↓4   =    2 xor 6
541278542243
    ↓反序
342245872145

。。。

341215172145
    ↓5   =   4 xor 1
341215172155
    ↓反序
551271512143
转换成C的代码如下:res = 0;
cres = m_jiqima;
for(int x = 0;x < m_jiqima.GetLength()-1;x++,res++)
{
    char a,b;
    char *d;
    if(res == cstr.GetLength())res = 0;

    a = cres.GetAt(x);//242245872125
    b = cstr.GetAt(res);//16048

    a ^= b;
    if(a > 9) a = 1;
    itoa(a,&b,10);

    cres.Delete(x);
    cres.Insert(x,b);
    d = (LPSTR)(LPCTSTR)cres;
    cres = StrReverse(d);
}

MessageBox(cres);
第二个循环结束了,休息一下,明天在继续吧~~~

下面看第三个循环:005F2DDB   >8B16          mov   edx, dword ptr             ;将运算出来的字符串给EDX
005F2DDD   . |52            push    edx                               ; /String
005F2DDE   . |FF15 30104000 call    dword ptr [<&msvbvm60.__vbaLenBst>; \__vbaLenBstr
005F2DE4   . |83F8 12       cmp   eax, 12                           ;结果应该是18位
005F2DE7   . |0F8D D5000000 jge   005F2EC2
005F2DED   . |8B06          mov   eax, dword ptr
005F2DEF   . |50            push    eax                               ; /String
005F2DF0   . |FF15 30104000 call    dword ptr [<&msvbvm60.__vbaLenBst>; \取出计算的字符串的长度
005F2DF6   . |8BC8          mov   ecx, eax
005F2DF8   . |FF15 80114000 call    dword ptr [<&msvbvm60.__vbaI2I4>] ;msvbvm60.__vbaI2I4
005F2DFE   . |8985 D8FEFFFF mov   dword ptr , eax
005F2E04   . |C745 E8 01000>mov   dword ptr , 1
005F2E0B   > |66:8B8D D8FEF>mov   cx, word ptr
005F2E12   . |66:394D E8    cmp   word ptr , cx
005F2E16   .^ 7F C3         jg      short 005F2DDB
005F2E18   . |8B16          mov   edx, dword ptr
005F2E1A   . |52            push    edx                               ; /String
005F2E1B   . |FF15 F0114000 call    dword ptr [<&msvbvm60.rtcStrRever>; \将上一个字符倒序
005F2E21   . |0FBF4D E8   movsx   ecx, word ptr
005F2E25   . |8945 9C       mov   dword ptr , eax
005F2E28   . |8D45 B4       lea   eax, dword ptr
005F2E2B   . |50            push    eax                               ; /Length8
005F2E2C   . |8D95 44FFFFFF lea   edx, dword ptr          ; |
005F2E32   . |51            push    ecx                               ; |Start
005F2E33   . |8D45 A4       lea   eax, dword ptr          ; |
005F2E36   . |52            push    edx                               ; |dString8
005F2E37   . |50            push    eax                               ; |RetBUFFER
005F2E38   . |C745 94 08000>mov   dword ptr , 8             ; |
005F2E3F   . |C745 BC 01000>mov   dword ptr , 1             ; |
005F2E46   . |C745 B4 02000>mov   dword ptr , 2             ; |
005F2E4D   . |89B5 4CFFFFFF mov   dword ptr , esi         ; |
005F2E53   . |C785 44FFFFFF>mov   dword ptr , 4008          ; |
005F2E5D   . |FF15 40114000 call    dword ptr [<&msvbvm60.rtcMidCharV>; \rtcMidCharVar
005F2E63   . |8D4D 94       lea   ecx, dword ptr          ;得到5,1
005F2E66   . |8D55 A4       lea   edx, dword ptr
005F2E69   . |51            push    ecx
005F2E6A   . |8D45 84       lea   eax, dword ptr
005F2E6D   . |52            push    edx
005F2E6E   . |50            push    eax
005F2E6F   . |FF15 38124000 call    dword ptr [<&msvbvm60.__vbaVarCat>;msvbvm60.__vbaVarCat
005F2E75   . |50            push    eax
005F2E76   . |FF15 2C104000 call    dword ptr [<&msvbvm60.__vbaStrVar>;msvbvm60.__vbaStrVarMove
005F2E7C   . |8BD0          mov   edx, eax
005F2E7E   . |8BCE          mov   ecx, esi
005F2E80   . |FFD3          call    ebx
005F2E82   . |8D4D 84       lea   ecx, dword ptr
005F2E85   . |8D55 A4       lea   edx, dword ptr
005F2E88   . |51            push    ecx
005F2E89   . |8D45 94       lea   eax, dword ptr
005F2E8C   . |52            push    edx
005F2E8D   . |8D4D B4       lea   ecx, dword ptr
005F2E90   . |50            push    eax
005F2E91   . |51            push    ecx
005F2E92   . |6A 04         push    4
005F2E94   . |FFD7          call    edi
005F2E96   . |8B16          mov   edx, dword ptr
005F2E98   . |83C4 14       add   esp, 14
005F2E9B   . |52            push    edx                               ; /String
005F2E9C   . |FF15 30104000 call    dword ptr [<&msvbvm60.__vbaLenBst>; \__vbaLenBstr
005F2EA2   . |83F8 12       cmp   eax, 12
005F2EA5   .^\0F8D 30FFFFFF jge   005F2DDB
005F2EAB   .B8 02000000   mov   eax, 2
005F2EB0   .66:0345 E8    add   ax, word ptr
005F2EB4   .0F80 72060000 jo      005F352C
005F2EBA   .8945 E8       mov   dword ptr , eax
005F2EBD   .^ E9 49FFFFFF   jmp   005F2E0B
    这个循环就很容易看明白了,就是,如果第二个循环得到的字符串如果不够18位,则取第一个字母贴到字符串后面,如果还不够,则将新的字符串倒序,取第三个字母,如果还不够18位,则再倒序,取第5个字母,贴到字符串后面,依次类推……
转换成C的代码如下:


代码:
for(i = 0;cres.GetLength() < 18;i += 2)
{
    char abc;
    char *d;
    abc = cres.GetAt(i);
    d = (LPSTR)(LPCTSTR)cres;
    cres = StrReverse(d);
    cres += abc;
}
MessageBox(cres);
说实话,到这里我反而觉得一切都不是像一开始那么有压力了,似乎这个程序一下就变简单了一样!很神奇哦~~~,这个循环我只用了5分钟就看明白了~~~
    这个是我第一次逆向分析一个软件的算法,虽然耗用了很多的时间,但是收获真的很多,帖出来与大家一起分享!



--------------------------------------------------------------------------------
【经验总结】
    本来以为,VB开发软件很容易,调试VB的程序也应该差不多的^_^,可是这个程序我也算坚持下来,分析完了~~~,收获不少,大概总结如下,希望能对像我一样菜的朋友能有所帮助:
    1、不要怀疑自己的能力:我没有学过汇编语言!但是我查着汇编指令大全也可以大概的分析出来!
    2、做事情要有耐心和毅力,不要轻言放弃:分析这个程序,我真的很多次想要放弃,因为我不知道该如何分析VB的程序,甚至它使用的函数我都查不到是什么意思,怎么用!
    3、看来要学破解,不仅要JAVA学的好,VB也要通的哈~~~~~~
      4、总感觉破解很难,很多人叫我大牛,说实话我曾经迷失过自己,但是我算什么呢菜鸟一个!!
--------------------------------------------------------------------------------
【版权声明】: 本文原创于 聚星亭 , 转载请注明作者并保持文章的完整, 谢谢!

                                                       2008年07月22日 13:05:44

[ 本帖最后由 bester 于 2009-2-13 03:22 编辑 ]
页: [1]
查看完整版本: 赚取权限第二贴之某打字练习软件的注册算法分析笔记