8.3 serial三星难度
查壳,VB写的。没壳。
还是一堆德语
百度翻译修改,只知道正确和错误是翻译对了。其它就不清楚了。
运行效果如下:
不管怎么样。先尝试BP rtcMsgBox,看看能不能断得下来。断下来了。
这里面应该是处理错误的子函数,因为一开始就已经在处理错误的操作了。所以应该返回上一层。
在堆栈窗口中选中最上面那写着返回的一行,回车,返回上层调用。如下图。
再往上拉,就会看到有关于错误和提示,还有一些操作。先找到函数头。
往上拉先久才看到函数开头,之前的断点可以去掉了,在00401E20这里下断,重载运行,看看它会不会断下来。断下来了就说明是正确的。如果不是,那就说明不是这里,就得往下拉,寻找可疑的地方来断下。
在00401EC2处,获取用户输入的内容,ebp-0x58堆栈出现用户输入的内容
注:
lea edx,var1 ;变量1的地址放到edx
lea ecx,var2 ;变量2的地址放到ecx
call __vbaVarMove ;把变量1赋值给变量2
其中,单步到这一步,有一条算法:遍历各个字符串和真实的key比较:
00401F68 > /85C0 test eax,eax 00401F6A . |0F84 BB000000 je Andréna.0040202B 00401F70 . |8D55 94 lea edx,dword ptr ss:[ebp-0x6C] 00401F73 . |8D45 DC lea eax,dword ptr ss:[ebp-0x24] 00401F76 . |52 push edx 00401F77 . |50 push eax 00401F78 . |C745 9C 01000>mov dword ptr ss:[ebp-0x64],0x1 00401F7F . |C745 94 02000>mov dword ptr ss:[ebp-0x6C],0x2 00401F86 . |FF15 90414000 call dword ptr ds:[<&MSVBVM50.__vbaI4Var>; MSVBVM50.__vbaI4Var 00401F8C . |8D4D BC lea ecx,dword ptr ss:[ebp-0x44] ; | 00401F8F . |50 push eax ; |Start = 0x12F450 00401F90 . |8D55 84 lea edx,dword ptr ss:[ebp-0x7C] ; | 00401F93 . |51 push ecx ; |dString8 = 00120003 00401F94 . |52 push edx ; |RetBUFFER = 0012F408 00401F95 . |FF15 34414000 call dword ptr ds:[<&MSVBVM50.#632>] ; \rtcMidCharVar 00401F9B . |8D45 84 lea eax,dword ptr ss:[ebp-0x7C] 00401F9E . |8D4D A8 lea ecx,dword ptr ss:[ebp-0x58] 00401FA1 . |50 push eax ; /String8 = 0012F450 00401FA2 . |51 push ecx ; |ARG2 = 00120003 00401FA3 . |FF15 64414000 call dword ptr ds:[<&MSVBVM50.__vbaStrVa>; \__vbaStrVarVal 00401FA9 . |50 push eax ; /String = "" 00401FAA . |FF15 08414000 call dword ptr ds:[<&MSVBVM50.#516>] ; \rtcAnsiValueBstr 00401FB0 . |66:05 0A00 add ax,0xA 00401FB4 . |0F80 B0020000 jo Andréna.0040226A 00401FBA . |0FBFD0 movsx edx,ax 00401FBD . |52 push edx 00401FBE . |FF15 70414000 call dword ptr ds:[<&MSVBVM50.#537>] ; MSVBVM50.rtcBstrFromAnsi 00401FC4 . |8985 7CFFFFFF mov dword ptr ss:[ebp-0x84],eax 00401FCA . |8D45 CC lea eax,dword ptr ss:[ebp-0x34] 00401FCD . |8D8D 74FFFFFF lea ecx,dword ptr ss:[ebp-0x8C] 00401FD3 . |50 push eax 00401FD4 . |8D95 64FFFFFF lea edx,dword ptr ss:[ebp-0x9C] 00401FDA . |51 push ecx 00401FDB . |52 push edx 00401FDC . |C785 74FFFFFF>mov dword ptr ss:[ebp-0x8C],0x8 00401FE6 . |FFD3 call ebx ; MSVBVM50.__vbaVarCat 00401FE8 . |8BD0 mov edx,eax 00401FEA . |8D4D CC lea ecx,dword ptr ss:[ebp-0x34] 00401FED . |FFD6 call esi ; MSVBVM50.__vbaVarMove 00401FEF . |8D4D A8 lea ecx,dword ptr ss:[ebp-0x58] 00401FF2 . |FF15 B0414000 call dword ptr ds:[<&MSVBVM50.__vbaFreeS>; MSVBVM50.__vbaFreeStr 00401FF8 . |8D85 74FFFFFF lea eax,dword ptr ss:[ebp-0x8C] 00401FFE . |8D4D 84 lea ecx,dword ptr ss:[ebp-0x7C] 00402001 . |50 push eax 00402002 . |8D55 94 lea edx,dword ptr ss:[ebp-0x6C] 00402005 . |51 push ecx 00402006 . |52 push edx 00402007 . |6A 03 push 0x3 00402009 . |FFD7 call edi ; MSVBVM50.__vbaFreeVarList 0040200B . |83C4 10 add esp,0x10 0040200E . |8D85 ECFEFFFF lea eax,dword ptr ss:[ebp-0x114] 00402014 . |8D8D FCFEFFFF lea ecx,dword ptr ss:[ebp-0x104] 0040201A . |8D55 DC lea edx,dword ptr ss:[ebp-0x24] 0040201D . |50 push eax ; /TMPend8 = 0012F450 0040201E . |51 push ecx ; |TMPstep8 = 00120003 0040201F . |52 push edx ; |Counter8 = 0012F408 00402020 . |FF15 A4414000 call dword ptr ds:[<&MSVBVM50.__vbaVarFo>; \__vbaVarForNext 00402026 .^\E9 3DFFFFFF jmp Andréna.00401F68
算法看了半天。都看不懂。因为没学过VB.所以只能。。去吾爱论坛看答案了。。
算法分析如下:
在VB中,使用了 __vbaVarForInit,__vbaFreeVarList,__vbaVarForNext 三个函数完成了一个For循环(参看上面的汇编代码),再循环中,每一次通过rtcMidCharVar取出一个字符,然后使用 rtcAnsiValueBstr 将字符转换为ANSII码值,将ANSII值加上0x0A之后再转换回字符,最后组成的字符串与"kXy^rO|*yXo*m\kMuOn*+"比较,比较的结果决定je跳转的成功和失败。
下面使用代码反计算Key值:
C/CPP代码:
#include "stdafx.h" #include "iostream" int _tmain(int argc, _TCHAR* argv[]) { char keyCode[100] = "kXy^rO|*yXo*m\\kMuOn*+"; char keyOld[100] = {0}; int nLen = strlen(keyCode); printf("%d\r\n",nLen); for ( int i=0;i<nLen;i++ ) { keyOld[i] = keyCode[i] - 0x0A; } printf("Key: %s\r\n",keyOld); system("pause"); return 0; }
故甚爱必大费,多藏必厚亡。知足不辱,知止不殆,可以长入。