赚取权限第二贴之某打字练习软件的注册算法分析笔记
帖第二篇了,看现在的破解业界,几乎人人都是高手,正如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]