算法分析第一课 -- 超级视频合并软件 算法分析 回帖有钱
本帖最后由 LYQingYe 于 2015-8-27 18:35 编辑{:6_205:}几天没法教程,手痒痒。{:5_121:}因为是假期 13天 ,所以我打算弄一个算法分析系列教程。现在是第一课,希望能得到大家的支持。{:5_124:}一边分析一天写帖的,所以难免会有些错误,希望大家指出,共同学习进步。{:6_208:}教程我就不隐藏了,回帖有钱领哦。我发教程只为共同学习不为什么,只求大家热心回复。中奖概率 50%每次5块钱,我是穷人
软件名称:超级视频合并软件 V2.20
编译器:貌似 Delphi6-7 {:6_207:} 无壳。
这个代码框让我数据丢失了两次,我又重新编过 效果不是很好,真失败。
正常情况下,打开弹出一个NAG窗口 要你注册还是试用,未注册版本合并视频后会有水印。下断点
MessageboxA 就可以找到关键 CALL 在这是 算法课,我就不说明了,很简单的。
从按钮事件开始_TFrm_Reg_Btn_RegClick proc near 0057EAC8
push ebp
mov ebp, esp
xor ecx, ecx
push ecx
push ecx
push ecx
push ecx
push ecx
push ecx
push ebx
mov ebx, eax
xor eax, eax
push ebp
push offset loc_57EC4F
push dword ptr fs:
mov fs:, esp
lea edx,
mov eax, ; this
call @Controls@TControl@GetText$qqrv ; TControl::GetText(void)
mov eax, EAX = 用户名 这里我们用 XUEPOJIE 来代替用户名
call unknown_libname_81 ; 取用户名长度赋值给EAX
test eax, eax 判断 EAX 是否等于 0用TEST EAX,EAX 是常用的方法来判断一个寄存器内容是否为 0。
jnz short loc_57EB2A 不为0 则跳转 到 LOC_57EB2A</font>loc_57EB2A:
lea edx,
mov eax, ; this
call @Controls@TControl@GetText$qqrv ; GetText(void)
mov eax, EAX = 假注册码 这里我们用 8888888888888888888888888代替注册码。
call unknown_libname_81 ; 取假码长度 给EAX
test eax, eax 判断假码长度是否为0
jnz short loc_57EB70 不为0则跳,必须要跳走。</font>
static/image/hrline/5.gif
loc_57EBFB核心算法CALL下面接着分析
loc_57EBFB 里面有四个 CALLloc_004E0D24 loc_004E0B4C(包含全部算法代码) loc_004047E8 loc_00403D04
004E0B66 push ebp
004E0B67 push 004E0D0A
004E0B6C push dword ptr fs:
004E0B6F mov dword ptr fs:, esp
004E0B72 mov eax,
004E0B75 call 004043C0
004E0B7A lea edx,
004E0B7D mov eax, edi
004E0B7F call 004E0AE4
004E0B84 mov eax, ;EAX = 用户名
004E0B87 call 0040469C ;计算的用户名长度
004E0B8C mov esi, eax
004E0B8E test esi, esi
004E0B90 jle short 004E0BC2 ;判断 是否为 0
004E0B92 mov ebx, 0x1 ;ebx 初始化 为0
004E0B97 lea edx,
004E0B9A mov eax, edi
004E0B9C call 004E0AE4
004E0BA1 mov eax, ;eax = 用户名地址
004E0BA4 movzx eax, byte ptr ;eax = 用户名第一位 ASICC值
004E0BA9 lea ecx,
004E0BAC xor edx, edx
004E0BAE call 00409528 ;需要分析
第一层算法
004093C8 or cl, cl 判断cl是否为0 cl = 10固定的
004093CA jnz short 004093E3 不为0不跳
004093CC or eax, eax
004093CE jns short 004093DE
004093D0 neg eax
004093D2 call 004093DE
004093D7 mov al, 0x2D
004093D9 inc ecx
004093DA dec esi
004093DB mov byte ptr , al
004093DD retn
004093DE mov ecx, 0xA
004093E3 push edx
004093E4 push esi
004093E5 xor edx, edx ;edx 清零
004093E7 div ecx ;此时 eax =X的ASCII 值 58 eax / ecx 商在 eax 余数在 edx
004093E9 dec esi ;esi - 1
004093EA add dl, 0x30 ;余数 + 0x30
004093ED cmp dl, 0x3A ;小于则跳转
004093F0 jb short 004093F5
004093F2 add dl, 0x7
004093F5 mov byte ptr , dl 处理后的数据放到 esi指向的内存空间
004093F7 or eax, eax 判断 eax是否为0 为0不跳
004093F9 jnz short 004093E5
第一次循环 : eax = 58 = 'X' ecx = 10 eax/ecx商=eax = 5 余数 = 8 =edx余数+30 = 8+30= 38放入 esi指向空间
第二次循环 eax = 5ecx = 10 eax /ecx 商 = 0 =eax循环可以跳走了余数 =edx = 5 余数 +30 =35esi-1 放入 前一个字节的空间
相当于3538 我们在内存看下 是不是感到很奇怪 这个数值 刚到 等于 一个 字符串 '58' 这个字符串 刚到等于 我们用户名第一个 字符的 ASCII值, 所以 第一层算法 只是将用户名的 ASCII值 转化为 字符串
ASCII "585545504F4A4945"
004E0BB3 mov edx, ;edx 等于 处理 后的 字符串
004E0BB6 lea eax,
004E0BB9 call 004046A4
004E0BBE inc ebx
004E0BBF dec esi
004E0BC0 jnz short 004E0B97
004E0BB3 mov edx, ;edx 等于 处理后的字符串地址004E0BB6 lea eax, 004E0BB9 call 004046A4004E0BBE inc ebx004E0BBF dec esi004E0BC0 jnz short 004E0B97
下面就是第二层算法 ,其实没什么作用 004E0BC2 mov eax, ;将 运算的 东东 放到eax004E0BC5 call 0040469C ;将 这字符串 前 4个 字节的 内容 给 eax004E0BCA mov esi, eax ;eax 给 esi004E0BCC test esi, esi ;判断 esi是否 为 0004E0BCE jle short 004E0BFC004E0BD0 mov ebx, 0x1 ;ebx 给0x1貌似要 计数器004E0BD5 mov eax, ;运算后的 假吗 给 eax004E0BD8 call 0040469C ;还是 刚才 那样 给前4个字节 数据 给 eax004E0BDD sub eax, ebx ;eax- ebx004E0BDF mov edx, ;假吗运算之 给 edx004E0BE2 mov dl, byte ptr ;第一次 取最后 一位004E0BE5 lea eax, ;估计 又是 将此 东西 放入缓冲区004E0BE8 call 004045A8 004E0BED mov edx, 004E0BF0 lea eax, 004E0BF3 call 004046A4004E0BF8 inc ebx004E0BF9 dec esi004E0BFA jnz short 004E0BD5第二层算法作用也就是 把第一层算法得出的字符串倒过来ASCII "5494A4F405545585"
004E0BFC lea eax, 将处理后的字符串 的二级指针给转化为 一级指针给eax 这个是第一层算法算出的004E0BFF push eax 压入栈,保存起来004E0C00 mov ecx, 0x4 初始化变量 eax = 0x4004E0C05 mov edx, 0x1 初始化变量 edx = 0x1004E0C0A mov eax, ;将倒转后的字符串也就是第二层算法 后的字符串地址给eax 004E0C0D call 004048FC 执行后 eax = 倒转字符串前四个字节 5494 字符串的二级指针004E0C12 lea eax, 二级指针给eax 转换为 一级指针004E0C15 push eax 指针入栈 保存004E0C16 mov ecx, 0x4 初始化值004E0C1B mov edx, 0x5 初始化值 004E0C20 mov eax, 倒转字符串地址给 eax 004E0C23 call 004048FC 执行后 eax = 倒转后字符串 接着在后四位 4AF4字符串的二级指针 004E0C28 mov eax, 将前四位字符串地址给eax004E0C2B call 0040469C 计算出他的长度004E0C30 cmp eax, 0x4 判断长度是否等于 0x4 等于则跳,我先撤了。已经跳了004E0C33 jge short 004E0C64004E0C35 mov eax, 004E0C38 call 0040469C004E0C3D mov ebx, eax004E0C3F cmp ebx, 0x3004E0C42 jg short 004E0C64004E0C44 /lea ecx, 004E0C47 |mov eax, ebx004E0C49 |shl eax, 0x2004E0C4C |xor edx, edx004E0C4E |call 00409528004E0C53 |mov edx, 004E0C56 |lea eax, 004E0C59 |call 004046A4004E0C5E |inc ebx004E0C5F |cmp ebx, 0x4004E0C62 \jnz short 004E0C44004E0C64 mov eax, 接着后四位的字符串地址给eax 4AF4
004E0C67 call 0040469C 计算器其长度004E0C6C cmp eax, 0x4 判断长度 跳了004E0C6F jge short 004E0CA0004E0C71 mov eax, 004E0C74 call 0040469C004E0C79 mov ebx, eax004E0C7B cmp ebx, 0x3004E0C7E jg short 004E0CA0004E0C80 /lea ecx, 004E0C83 |mov eax, ebx004E0C85 |shl eax, 0x2004E0C88 |xor edx, edx004E0C8A |call 00409528004E0C8F |mov edx, 004E0C92 |lea eax, 004E0C95 |call 004046A4004E0C9A |inc ebx004E0C9B |cmp ebx, 0x4004E0C9E \jnz short 004E0C80004E0CA0 lea eax, 004E0CA3 push eax004E0CA4 mov eax, dword ptr 在这产生一个新的字符串 vj268v2013 不要奇怪这个字符串是固定的 就是这个软件的exe名称和版本 004E0CA7 mov ecx, 0x4 004E0CAC mov edx, 0x1004E0CB1 call 004048FC 取前四位字符串 vj26004E0CB6 push 004E0CB9 push 004E0D20 ;UNICODE "-"004E0CBE push 004E0CC1 lea eax, 004E0CC4 push eax004E0CC5 mov eax, dword ptr 004E0CC8 mov ecx, 0x5004E0CCD mov edx, 0x5004E0CD2 call 004048FC 取后 5位字符串 8v201004E0CD7 push 004E0CDA push 004E0D20 ;UNICODE "-" 看到这 杠号是不是很熟悉啊,哈哈 你已经拆到了004E0CDF push 004E0CE2 mov eax, 004E0CE5 mov edx, 0x6004E0CEA call 0040475C004E0CEF xor eax, eax004E0CF1 pop edx004E0CF2 pop ecx004E0CF3 pop ecx004E0CF4 mov dword ptr fs:, edx004E0CF7 push 004E0D11004E0CFC lea eax, 004E0CFF mov edx, 0xA004E0D04 call 004043E4到最后就是 将前面出现过的字符串组装了,我就不废话了 vj26-54948v201-A4F4 5494是将用户名经过二层算法获得的前四个字节的字符串 A4F4是在后四位的字符串 其他的就是这个软件的 exe名称了 最后这个就是注册码了。。我们测试下。。
注册成功,哈哈,肚子太饿了,我就偷懒下,写这个帖子花了我三个小时,边分析边写帖子,大伙给我点动力把。一路 艰难险阻是不是都过来了?是否体验到算法带来的成就感?本次教程到此结束,我是 LYQingYe 我爱雪坡姐, 感谢大家支持。
沙发我速度怎么样 看到有钱我就来了谢谢楼主 我是来拿HB的 嗯,领钱走人了。 回帖真的有钱吗。我是来蹭钱的。。 嘿嘿 我是来蹭钱的 膜拜算法牛,学习下怎么样的算法过程 ningzhonghui 发表于 2015-8-26 21:18
膜拜算法牛,学习下怎么样的算法过程
数据丢失两次了,分析得不是很全了。谢谢支持 不错。学习了。