通过字符串搜索或者在弹窗后断下程序可以找到关键处理函数:
可以看到首先:
004020A8 . FF15 14414000 call dword ptr ds:[<&MSVBVM50.__vbaHresu>; MSVBVM50.__vbaHresultCheckObj
004020AE > 8B45 A8 mov eax,dword ptr ss:[ebp-0x58] ; name
004020B1 . 8975 A8 mov dword ptr ss:[ebp-0x58],esi
004020B4 . 8B35 FC404000 mov esi,dword ptr ds:[<&MSVBVM50.__vbaVa>; MSVBVM50.__vbaVarMove
004020BA . 8D55 94 lea edx,dword ptr ss:[ebp-0x6C]
004020BD . 8D4D BC lea ecx,dword ptr ss:[ebp-0x44]
004020C0 . 8945 9C mov dword ptr ss:[ebp-0x64],eax
004020C3 . C745 94 08000>mov dword ptr ss:[ebp-0x6C],0x8
004020CA . FFD6 call esi ; <&MSVBVM50.__vbaVarMove>
004020CC . 8D4D A4 lea ecx,dword ptr ss:[ebp-0x5C]
004020CF . FF15 B4414000 call dword ptr ds:[<&MSVBVM50.__vbaFreeO>; MSVBVM50.__vbaFreeObj
004020D5 . B8 01000000 mov eax,0x1
004020DA . 8D8D 54FFFFFF lea ecx,dword ptr ss:[ebp-0xAC]
004020E0 . 8985 5CFFFFFF mov dword ptr ss:[ebp-0xA4],eax
004020E6 . 8985 4CFFFFFF mov dword ptr ss:[ebp-0xB4],eax
004020EC . 8D55 BC lea edx,dword ptr ss:[ebp-0x44]
004020EF . 51 push ecx ; /Step8
004020F0 . 8D45 94 lea eax,dword ptr ss:[ebp-0x6C] ; |
004020F3 . BB 02000000 mov ebx,0x2 ; |
004020F8 . 52 push edx ; |/var18
004020F9 . 50 push eax ; ||retBuffer8
004020FA . 899D 54FFFFFF mov dword ptr ss:[ebp-0xAC],ebx ; ||
00402100 . 899D 44FFFFFF mov dword ptr ss:[ebp-0xBC],ebx ; ||
00402106 . FF15 18414000 call dword ptr ds:[<&MSVBVM50.__vbaLenVa>; |\__vbaLenVar
0040210C . 8D8D 44FFFFFF lea ecx,dword ptr ss:[ebp-0xBC] ; |
00402112 . 50 push eax ; |End8
00402113 . 8D95 E8FEFFFF lea edx,dword ptr ss:[ebp-0x118] ; |
00402119 . 51 push ecx ; |Start8
0040211A . 8D85 F8FEFFFF lea eax,dword ptr ss:[ebp-0x108] ; |
00402120 . 52 push edx ; |TMPend8
00402121 . 8D4D DC lea ecx,dword ptr ss:[ebp-0x24] ; |
00402124 . 50 push eax ; |TMPstep8
00402125 . 51 push ecx ; |Counter8
00402126 . FF15 20414000 call dword ptr ds:[<&MSVBVM50.__vbaVarFo>; \__vbaVarForInit 重复执行初始化
程序获取了len(name)
而后进行了初始化操作,具体没看初始化里面在干啥
推测是结合下面的:
004021C8 . 51 push ecx ; /TMPend8
004021C9 . 52 push edx ; |TMPstep8
004021CA . 50 push eax ; |Counter8
004021CB . FF15 AC414000 call dword ptr ds:[<&MSVBVM50.__vbaVarFo>; \__vbaVarForNext
实现一个for循环操作,因为动态调试时候发现中间的循环操作次数是len(name),同时看到中间:
00402132 > /85C0 test eax,eax
00402134 . |0F84 9C000000 je Andréna.004021D6
0040213A . |8D55 94 lea edx,dword ptr ss:[ebp-0x6C]
0040213D . |8D45 DC lea eax,dword ptr ss:[ebp-0x24]
00402140 . |52 push edx
00402141 . |50 push eax
00402142 . |C745 9C 01000>mov dword ptr ss:[ebp-0x64],0x1
00402149 . |895D 94 mov dword ptr ss:[ebp-0x6C],ebx
0040214C . |FF15 90414000 call dword ptr ds:[<&MSVBVM50.__vbaI4Var>; MSVBVM50.__vbaI4Var
00402152 . |8D4D BC lea ecx,dword ptr ss:[ebp-0x44] ; |
00402155 . |50 push eax ; |Start
00402156 . |8D55 84 lea edx,dword ptr ss:[ebp-0x7C] ; |(input_name)
00402159 . |51 push ecx ; |dString8
0040215A . |52 push edx ; |RetBUFFER
0040215B . |FF15 38414000 call dword ptr ds:[<&MSVBVM50.#632>] ; \rtcMidCharVar
00402161 . |8D45 84 lea eax,dword ptr ss:[ebp-0x7C]
00402164 . |8D4D A8 lea ecx,dword ptr ss:[ebp-0x58]
00402167 . |50 push eax ; /String8
00402168 . |51 push ecx ; |ARG2
00402169 . |FF15 70414000 call dword ptr ds:[<&MSVBVM50.__vbaStrVa>; \__vbaStrVarVal
0040216F . |50 push eax ; /String
00402170 . |FF15 0C414000 call dword ptr ds:[<&MSVBVM50.#516>] ; \rtcAnsiValueBstr
00402176 . |66:8985 4CFFF>mov word ptr ss:[ebp-0xB4],ax ; name[i]
0040217D . |8D55 CC lea edx,dword ptr ss:[ebp-0x34]
00402180 . |8D85 44FFFFFF lea eax,dword ptr ss:[ebp-0xBC]
00402186 . |52 push edx ; /var18
00402187 |8D8D 74FFFFFF lea ecx,dword ptr ss:[ebp-0x8C] ; |
0040218D |50 push eax ; |var28
0040218E |51 push ecx ; |saveto8
0040218F . |899D 44FFFFFF mov dword ptr ss:[ebp-0xBC],ebx ; |
00402195 . |FF15 94414000 call dword ptr ds:[<&MSVBVM50.__vbaVarAd>; \__vbaVarAdd
0040219B . |8BD0 mov edx,eax ; 两变量相加
0040219D . |8D4D CC lea ecx,dword ptr ss:[ebp-0x34]
004021A0 . |FFD6 call esi
004021A2 . |8D4D A8 lea ecx,dword ptr ss:[ebp-0x58]
004021A5 . |FF15 B8414000 call dword ptr ds:[<&MSVBVM50.__vbaFreeS>; MSVBVM50.__vbaFreeStr
004021AB . |8D55 84 lea edx,dword ptr ss:[ebp-0x7C]
004021AE . |8D45 94 lea eax,dword ptr ss:[ebp-0x6C]
004021B1 . |52 push edx
004021B2 . |50 push eax
004021B3 . |53 push ebx
004021B4 . |FFD7 call edi
004021B6 . |83C4 0C add esp,0xC
004021B9 . |8D8D E8FEFFFF lea ecx,dword ptr ss:[ebp-0x118]
004021BF . |8D95 F8FEFFFF lea edx,dword ptr ss:[ebp-0x108]
004021C5 . |8D45 DC lea eax,dword ptr ss:[ebp-0x24]
004021C8 . |51 push ecx ; /TMPend8
004021C9 . |52 push edx ; |TMPstep8
004021CA . |50 push eax ; |Counter8
004021CB . |FF15 AC414000 call dword ptr ds:[<&MSVBVM50.__vbaVarFo>; \__vbaVarForNext
004021D1 .^\E9 5CFFFFFF jmp Andréna.00402132
其首先利用rtcMidCharVar取字符串中的字符,而后使用rtcAnsiValueBstr转化为对应ascii值,而后通过__vbaVarAdd不断相加
循环结束后即得到name每一位相加得到的结果
接下来:
004021D6 > \8D4D CC lea ecx,dword ptr ss:[ebp-0x34]
004021D9 . 8D95 54FFFFFF lea edx,dword ptr ss:[ebp-0xAC]
004021DF . 51 push ecx ; /var18
004021E0 . 8D45 94 lea eax,dword ptr ss:[ebp-0x6C] ; |
004021E3 . 52 push edx ; |var28
004021E4 . 50 push eax ; |SaveTo8
004021E5 . C785 5CFFFFFF>mov dword ptr ss:[ebp-0xA4],0x499602D2 ; |sum(name[i])*0x499602d2
004021EF . C785 54FFFFFF>mov dword ptr ss:[ebp-0xAC],0x3 ; |
004021F9 . FF15 5C414000 call dword ptr ds:[<&MSVBVM50.__vbaVarMu>; \__vbaVarMul
其利用vbaVarMul计算了:
sum(name[i])*0x499602d2
而后调用了两次一个函数:__vbaMidStmtVar
我没查到这个函数是干嘛的,不过通过其处理结果和参数大致可以猜测:
0040223A . 50 push eax ;目标位置
0040223B . 6A 09 push 0x9 ;位置,从1计数
0040223D . 6A 01 push 0x1
0040223F . 51 push ecx ;替换成的字符
00402240 . C785 5CFFFFFF>mov dword ptr ss:[ebp-0xA4],Andréna.0040>; -
0040224A . C785 54FFFFFF>mov dword ptr ss:[ebp-0xAC],0x8
00402254 . FFD3 call ebx
其会将传入对象先转化为字符串(例如刚才的乘积转换为10进制字符串),再根据参数将对应位置字符,参数大致猜测如上,这样两次分别替换第4和第9字节为"-":
0040220F . 51 push ecx
00402210 . 6A 04 push 0x4
00402212 . 8D95 54FFFFFF lea edx,dword ptr ss:[ebp-0xAC]
00402218 . 6A 01 push 0x1
0040221A . 52 push edx
0040221B . C785 5CFFFFFF>mov dword ptr ss:[ebp-0xA4],Andréna.0040>; -
00402225 . C785 54FFFFFF>mov dword ptr ss:[ebp-0xAC],0x8
0040222F . FFD3 call ebx ; <&MSVBVM50.__vbaMidStmtVar>
00402231 . 8D45 CC lea eax,dword ptr ss:[ebp-0x34]
00402234 . 8D8D 54FFFFFF lea ecx,dword ptr ss:[ebp-0xAC]
0040223A . 50 push eax
0040223B . 6A 09 push 0x9
0040223D . 6A 01 push 0x1
0040223F . 51 push ecx
00402240 . C785 5CFFFFFF>mov dword ptr ss:[ebp-0xA4],Andréna.0040>; -
0040224A . C785 54FFFFFF>mov dword ptr ss:[ebp-0xAC],0x8
00402254 . FFD3 call ebx
最后进行一次比较:
0040229E . 50 push eax ; /var18
0040229F . 51 push ecx ; |var28
004022A0 . C745 A8 00000>mov dword ptr ss:[ebp-0x58],0x0 ; |
004022A7 . C745 94 08800>mov dword ptr ss:[ebp-0x6C],0x8008 ; |
004022AE . FF15 48414000 call dword ptr ds:[<&MSVBVM50.__vbaVarTs>; \__vbaVarTstEq
004022B4 . 8D4D A4 lea ecx,dword ptr ss:[ebp-0x5C]
004022B7 . 8BD8 mov ebx,eax
004022B9 . FF15 B4414000 call dword ptr ds:[<&MSVBVM50.__vbaFreeO>; MSVBVM50.__vbaFreeObj
004022BF . 8D4D 94 lea ecx,dword ptr ss:[ebp-0x6C]
004022C2 . FF15 00414000 call dword ptr ds:[<&MSVBVM50.__vbaFreeV>; MSVBVM50.__vbaFreeVar
004022C8 . 66:85DB test bx,bx
004022CB . 0F84 C0000000 je Andréna.00402391 ; judge
利用__vbaVarTstEq判断我们输入的serial和name生成的真正序列号
虽然距离判断有free操作,但好像没影响
根据name求出序列号输入即可:
import sys
def get_serial(name):
sum=0
for i in name:
sum+=ord(i)
last=str(sum*0x499602d2)
last=last[0:3]+'-'+last[4:8]+'-'+last[9:]
return last
if __name__=="__main__":
name=sys.argv[1]
print get_serial(name)
#output:
#python crackme9.py beixiaozhi
#131-5185-6520