“调戏”反遭“反调戏”—记Visual Toolbar 的破解过程
cntrump
由于要做工具栏,在网上找到了Visual Toolbar这个工具,看了介绍挺不错的,下载回来之后发现软件要注册,但是这是个04年的软件,已经没法向作者购买了,更重要的原因是俺还在失业中,吃饭都成问题了,哪里还有钱注册呀~~
用PEID检测是UPX的老壳,直接手脱,过程不是重点反正能脱壳就行了。试着注册了一下,发现我最喜爱的MessageBox注册错误提示,太好了,下断bp MessageBoxA,中断下来后往上找,很容易找到一些敏感信息:
00407790 6A FF push -0x1
00407792 68 60A64900 push unpacked.0049A660
00407797 64:A1 00000000 mov eax,dword ptr fs:[0]
0040779D 50 push eax
0040779E 64:8925 0000000>mov dword ptr fs:[0],esp
004077A5 83EC 10 sub esp,0x10 ;程序用的是MFC所以取值部分比较啰嗦
004077A8 53 push ebx ;关键的代码我都用红色标出来了。
004077A9 55 push ebp
004077AA 56 push esi
004077AB 57 push edi
004077AC 8BF1 mov esi,ecx
004077AE 6A 01 push 0x1
004077B0 E8 6D1B0900 call <jmp.&mfc42.#CWnd::UpdateData_6334> ;获取输入的值
004077B5 8D4C24 14 lea ecx,dword ptr ss:[esp+0x14]
004077B9 E8 40180900 call <jmp.&mfc42.#CString::CString_540>
004077BE 8D4424 14 lea eax,dword ptr ss:[esp+0x14]
004077C2 33DB xor ebx,ebx
004077C4 50 push eax
004077C5 8D8E 4C0E0000 lea ecx,dword ptr ds:[esi+0xE4C]
004077CB 895C24 2C mov dword ptr ss:[esp+0x2C],ebx
004077CF E8 AA190900 call <jmp.&mfc42.#CWnd::GetWindowTextA_3874>
004077D4 51 push ecx
004077D5 8DBE 900E0000 lea edi,dword ptr ds:[esi+0xE90]
004077DB 8BCC mov ecx,esp
004077DD 896424 20 mov dword ptr ss:[esp+0x20],esp
004077E1 57 push edi
004077E2 E8 05180900 call <jmp.&mfc42.#CString::CString_535>
004077E7 51 push ecx
004077E8 8D5424 1C lea edx,dword ptr ss:[esp+0x1C]
004077EC 8BCC mov ecx,esp
004077EE 896424 20 mov dword ptr ss:[esp+0x20],esp
004077F2 52 push edx
004077F3 C64424 34 01 mov byte ptr ss:[esp+0x34],0x1
004077F8 E8 EF170900 call <jmp.&mfc42.#CString::CString_535>
004077FD 8D4424 18 lea eax,dword ptr ss:[esp+0x18]
00407801 885C24 30 mov byte ptr ss:[esp+0x30],bl;以上部分是取机器码等信息
00407805 50 push eax
00407806 E8 65A3FFFF call unpacked.00401B70 ; 注册验证部分
0040780B 83C4 0C add esp,0xC
0040780E 8B0F mov ecx,dword ptr ds:[edi]
00407810 C64424 28 02 mov byte ptr ss:[esp+0x28],0x2
00407815 8B41 F8 mov eax,dword ptr ds:[ecx-0x8]
00407818 83F8 04 cmp eax,0x4
0040781B 7F 35 jg short unpacked.00407852 ;用户名至少5位
0040781D 8D4C24 18 lea ecx,dword ptr ss:[esp+0x18]
00407821 E8 D8170900 call <jmp.&mfc42.#CString::CString_540>
00407826 6A 68 push 0x68
00407828 8D4C24 1C lea ecx,dword ptr ss:[esp+0x1C]
0040782C C64424 2C 03 mov byte ptr ss:[esp+0x2C],0x3
00407831 E8 84190900 call <jmp.&mfc42.#CString::LoadStringA_4160>
00407836 8B5424 18 mov edx,dword ptr ss:[esp+0x18]
0040783A 53 push ebx
0040783B 53 push ebx
0040783C 52 push edx
0040783D 8BCE mov ecx,esi
0040783F E8 D81A0900 call <jmp.&mfc42.#CWnd::MessageBoxA_4224>
00407844 C64424 28 02 mov byte ptr ss:[esp+0x28],0x2
00407849 8D4C24 18 lea ecx,dword ptr ss:[esp+0x18]
0040784D E9 CB000000 jmp unpacked.0040791D
00407852 8B4C24 10 mov ecx,dword ptr ss:[esp+0x10]
00407856 8B86 940E0000 mov eax,dword ptr ds:[esi+0xE94]
0040785C 51 push ecx
0040785D 50 push eax
0040785E FF15 30495200 call dword ptr ds:[<&msvcrt._mbscmp>] ; MSVCRT._mbscmp ; 真假注册码比较
00407864 83C4 08 add esp,0x8
00407867 85C0 test eax,eax
00407869 75 78 jnz short unpacked.004078E3 ;关键跳,跳就失败。
0040786B 891D F0164D00 mov dword ptr ds:[0x4D16F0],ebx
00407871 E8 A01A0900 call <jmp.&mfc42.#AfxGetModuleState_1168>
00407876 8B3F mov edi,dword ptr ds:[edi]
00407878 8B68 04 mov ebp,dword ptr ds:[eax+0x4]
0040787B 57 push edi
0040787C 68 D4534C00 push unpacked.004C53D4 ; USER
00407881 68 C4534C00 push unpacked.004C53C4 ; VisualToolbar10
00407886 8BCD mov ecx,ebp
00407888 E8 831A0900 call <jmp.&mfc42.#CWinApp::WriteProfileStringA_6403>
0040788D 8B5424 10 mov edx,dword ptr ss:[esp+0x10]
00407891 8BCD mov ecx,ebp
00407893 52 push edx
00407894 68 C0534C00 push unpacked.004C53C0 ; SN
00407899 68 C4534C00 push unpacked.004C53C4 ; VisualToolbar10
0040789E E8 6D1A0900 call <jmp.&mfc42.#CWinApp::WriteProfileStringA_6403>
00401B70 6A FF push -0x1
00401B72 68 3F9F4900 push unpacked.00499F3F
00401B77 64:A1 00000000 mov eax,dword ptr fs:[0]
00401B7D 50 push eax
00401B7E 64:8925 0000000>mov dword ptr fs:[0],esp
00401B85 83EC 20 sub esp,0x20
00401B88 53 push ebx
00401B89 55 push ebp
00401B8A 56 push esi
00401B8B 33F6 xor esi,esi
00401B8D 57 push edi
00401B8E 897424 1C mov dword ptr ss:[esp+0x1C],esi
00401B92 8D4C24 20 lea ecx,dword ptr ss:[esp+0x20]
00401B96 C74424 38 02000>mov dword ptr ss:[esp+0x38],0x2
00401B9E E8 5B740900 call <jmp.&mfc42.#CString::CString_540>
00401BA3 8B4424 48 mov eax,dword ptr ss:[esp+0x48]
00401BA7 C64424 38 03 mov byte ptr ss:[esp+0x38],0x3
00401BAC C64424 24 56 mov byte ptr ss:[esp+0x24],0x56
00401BB1 C64424 25 69 mov byte ptr ss:[esp+0x25],0x69
00401BB6 8B68 F8 mov ebp,dword ptr ds:[eax-0x8]
00401BB9 C64424 26 73 mov byte ptr ss:[esp+0x26],0x73
00401BBE 83FD 0A cmp ebp,0xA ; 用户名位数和10比较
00401BC1 C64424 27 75 mov byte ptr ss:[esp+0x27],0x75
00401BC6 C64424 28 61 mov byte ptr ss:[esp+0x28],0x61
00401BCB C64424 29 6C mov byte ptr ss:[esp+0x29],0x6C
00401BD0 C64424 2A 54 mov byte ptr ss:[esp+0x2A],0x54
00401BD5 C64424 2B 42 mov byte ptr ss:[esp+0x2B],0x42
00401BDA C64424 2C 31 mov byte ptr ss:[esp+0x2C],0x31
00401BDF C64424 2D 30 mov byte ptr ss:[esp+0x2D],0x30
00401BE4 7C 05 jl short unpacked.00401BEB ; 如果大于10位,那么就分配10字节的空间。
00401BE6 BD 0A000000 mov ebp,0xA
00401BEB 55 push ebp ; 否则根据用户名位数分配内存。
00401BEC E8 1F740900 call <jmp.&mfc42.#operator new_823>
00401BF1 83C4 04 add esp,0x4
00401BF4 8D4C24 14 lea ecx,dword ptr ss:[esp+0x14]
00401BF8 8BF8 mov edi,eax
00401BFA E8 FF730900 call <jmp.&mfc42.#CString::CString_540>
00401BFF 68 30164D00 push unpacked.004D1630
00401C04 8D4C24 14 lea ecx,dword ptr ss:[esp+0x14]
00401C08 C64424 3C 04 mov byte ptr ss:[esp+0x3C],0x4
00401C0D E8 F8730900 call <jmp.&mfc42.#CString::CString_537>
00401C12 3BEE cmp ebp,esi
00401C14 C64424 38 05 mov byte ptr ss:[esp+0x38],0x5
00401C19 7E 53 jle short unpacked.00401C6E
00401C1B 8D4424 24 lea eax,dword ptr ss:[esp+0x24]
00401C1F 2BC7 sub eax,edi
00401C21 894424 18 mov dword ptr ss:[esp+0x18],eax
00401C25 EB 04 jmp short unpacked.00401C2B
00401C27 8B4424 18 mov eax,dword ptr ss:[esp+0x18]
00401C2B 8B4C24 48 mov ecx,dword ptr ss:[esp+0x48] ; esp+0x48是用户名
00401C2F 8A140E mov dl,byte ptr ds:[esi+ecx] ; 逐位取用户名,存入dl
00401C32 8B4C24 44 mov ecx,dword ptr ss:[esp+0x44] ; esp+0x44是机器码
00401C36 8A1C0E mov bl,byte ptr ds:[esi+ecx]; 逐位取机器码,存入bl
00401C39 8D0C3E lea ecx,dword ptr ds:[esi+edi]
00401C3C 8A0408 mov al,byte ptr ds:[eax+ecx] ; al 指向隐藏的字符串"VisualTB10"
00401C3F 32C3 xor al,bl
00401C41 32C2 xor al,dl
00401C43 0FBED0 movsx edx,al ; 用户名与机器码逐位异或,结果保存到edx中。
00401C46 8801 mov byte ptr ds:[ecx],al
00401C48 52 push edx
00401C49 8D4424 18 lea eax,dword ptr ss:[esp+0x18]
00401C4D 68 34504C00 push unpacked.004C5034 ; %d
00401C52 50 push eax
00401C53 E8 A0730900 call <jmp.&mfc42.#CString::Format_2818> ; 得到的值转化为字符串形式。
00401C58 83C4 0C add esp,0xC
00401C5B 8D4C24 14 lea ecx,dword ptr ss:[esp+0x14]
00401C5F 51 push ecx
00401C60 8D4C24 14 lea ecx,dword ptr ss:[esp+0x14]
00401C64 E8 9B730900 call <jmp.&mfc42.#CString::operator+=_939> ; 把字符串连接起来。
00401C69 46 inc esi
00401C6A 3BF5 cmp esi,ebp ; 循环次数是用户名的位数
00401C6C ^ 7C B9 jl short unpacked.00401C27
00401C6E 57 push edi
00401C6F E8 6C730900 call <jmp.&mfc42.#operator delete_825>
00401C74 8B7424 44 mov esi,dword ptr ss:[esp+0x44]
00401C78 83C4 04 add esp,0x4
00401C7B 8D5424 10 lea edx,dword ptr ss:[esp+0x10]
00401C7F 8BCE mov ecx,esi
00401C81 52 push edx
00401C82 E8 65730900 call <jmp.&mfc42.#CString::CString_535>
00401C87 BB 01000000 mov ebx,0x1
00401C8C 895C24 1C mov dword ptr ss:[esp+0x1C],ebx
00401C90 8D4C24 10 lea ecx,dword ptr ss:[esp+0x10]
00401C94 C64424 38 04 mov byte ptr ss:[esp+0x38],0x4
00401C99 E8 48730900 call <jmp.&mfc42.#CString::~CString_800>
00401C9E 8D4C24 14 lea ecx,dword ptr ss:[esp+0x14]
00401CA2 C64424 38 03 mov byte ptr ss:[esp+0x38],0x3
00401CA7 E8 3A730900 call <jmp.&mfc42.#CString::~CString_800>
00401CAC 8D4C24 20 lea ecx,dword ptr ss:[esp+0x20]
00401CB0 C64424 38 02 mov byte ptr ss:[esp+0x38],0x2
00401CB5 E8 2C730900 call <jmp.&mfc42.#CString::~CString_800>
00401CBA 8D4C24 44 lea ecx,dword ptr ss:[esp+0x44]
00401CBE 885C24 38 mov byte ptr ss:[esp+0x38],bl
00401CC2 E8 1F730900 call <jmp.&mfc42.#CString::~CString_800>
00401CC7 8D4C24 48 lea ecx,dword ptr ss:[esp+0x48]
00401CCB C64424 38 00 mov byte ptr ss:[esp+0x38],0x0
00401CD0 E8 11730900 call <jmp.&mfc42.#CString::~CString_800>
00401CD5 8B4C24 30 mov ecx,dword ptr ss:[esp+0x30]
00401CD9 8BC6 mov eax,esi
00401CDB 5F pop edi
00401CDC 5E pop esi
00401CDD 5D pop ebp
00401CDE 5B pop ebx
00401CDF 64:890D 0000000>mov dword ptr fs:[0],ecx
00401CE6 83C4 2C add esp,0x2C
00401CE9 C3 retn
DoDataExchange(DDX_SAVE); //从控件中取值
TCHAR szFlag[] = _T("VisualTB10");
TCHAR *p = szFlag;
m_strSN = _T(""); // m_strSN保存生成的注册码
CString csTemp;
if (m_strMCode.IsEmpty() || m_strUserName.IsEmpty() ||
(m_strUserName.GetLength() < 5))
return 0;
int nLen = m_strUserName.GetLength();
TCHAR *pstrNameBuffer = new TCHAR[nLen<10?nLen+1:10];
TCHAR *pstrMCodeBuffer = new TCHAR[m_strMCode.GetLength()+1];
lstrcpy(pstrNameBuffer, m_strUserName.GetBuffer(m_strUserName.GetLength()));
lstrcpy(pstrMCodeBuffer, m_strMCode.GetBuffer(m_strMCode.GetLength()));
for (int i = 0; i < (nLen<10?nLen:10); i++)
{
csTemp.Format(_T("%d"), p[i] ^ pstrMCodeBuffer[i] ^ pstrNameBuffer[i]);
m_strSN += csTemp;
}
DoDataExchange(DDX_LOAD); //显示到控件中。
0041BC54 BB 01000000 mov ebx,0x1
0041BC59 68 C4534C00 push unpacked.004C53C4 ; VisualToolbar10
0041BC5E 8BCE mov ecx,esi
0041BC60 891D F0164D00 mov dword ptr ds:[0x4D16F0],ebx
0041BC66 E8 57DC0700 call <jmp.&mfc42.#CWinApp::SetRegistryKey_6117>
0041BC6B 8D4424 08 lea eax,dword ptr ss:[esp+0x8]
0041BC6F 50 push eax
0041BC70 E8 EB5DFEFF call unpacked.00401A60 ; 生成机器码
0041BC75 83C4 04 add esp,0x4
0041BC78 68 D4534C00 push unpacked.004C53D4 ; USER
0041BC7D 68 D4534C00 push unpacked.004C53D4 ; USER
0041BC82 8D4C24 14 lea ecx,dword ptr ss:[esp+0x14]
0041BC86 68 C4534C00 push unpacked.004C53C4 ; VisualToolbar10
0041BC8B 51 push ecx
0041BC8C 8BCE mov ecx,esi
0041BC8E C78424 CC480000>mov dword ptr ss:[esp+0x48CC],0x0
0041BC99 E8 1EDC0700 call <jmp.&mfc42.#CWinApp::GetProfileStringA_3522>
0041BC9E 68 DC5A4C00 push unpacked.004C5ADC ; Password
0041BCA3 68 C0534C00 push unpacked.004C53C0 ; SN
0041BCA8 8D5424 20 lea edx,dword ptr ss:[esp+0x20]
0041BCAC 68 C4534C00 push unpacked.004C53C4 ; VisualToolbar10
0041BCB1 52 push edx
0041BCB2 8BCE mov ecx,esi
0041BCB4 889C24 CC480000 mov byte ptr ss:[esp+0x48CC],bl
0041BCBB E8 FCDB0700 call <jmp.&mfc42.#CWinApp::GetProfileStringA_3522>
0041BCC0 51 push ecx
0041BCC1 8D4424 10 lea eax,dword ptr ss:[esp+0x10]
0041BCC5 8BCC mov ecx,esp
0041BCC7 896424 20 mov dword ptr ss:[esp+0x20],esp
0041BCCB 50 push eax
0041BCCC C68424 C4480000>mov byte ptr ss:[esp+0x48C4],0x2
0041BCD4 E8 13D30700 call <jmp.&mfc42.#CString::CString_535>
0041BCD9 51 push ecx
0041BCDA 8D5424 10 lea edx,dword ptr ss:[esp+0x10]
0041BCDE 8BCC mov ecx,esp
0041BCE0 896424 1C mov dword ptr ss:[esp+0x1C],esp
0041BCE4 52 push edx
0041BCE5 C68424 C8480000>mov byte ptr ss:[esp+0x48C8],0x3
0041BCED E8 FAD20700 call <jmp.&mfc42.#CString::CString_535>
0041BCF2 8D4424 18 lea eax,dword ptr ss:[esp+0x18]
0041BCF6 C68424 C4480000>mov byte ptr ss:[esp+0x48C4],0x2
0041BCFE 50 push eax
0041BCFF E8 6C5EFEFF call unpacked.00401B70 ;注册验证的部份,在前面已经分析过了。
0041BD04 8B4C24 24 mov ecx,dword ptr ss:[esp+0x24]
0041BD08 8B5424 1C mov edx,dword ptr ss:[esp+0x1C]
0041BD0C 51 push ecx
0041BD0D 52 push edx
0041BD0E C68424 D0480000>mov byte ptr ss:[esp+0x48D0],0x4
0041BD16 FF15 30495200 call dword ptr ds:[<&msvcrt._mbscmp>] ; MSVCRT._mbscmp ; 真假码比较部分。
0041BD1C 83C4 14 add esp,0x14
0041BD1F 85C0 test eax,eax
0041BD21 75 07 jnz short unpacked.0041BD2A; 关键跳
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课