[新人持续炫耀贴] 可讨论 可装比 还有强行解答 捂脸
刚刚飞快地破解了http://www.52pojie.cn/thread-378612-1-1.html吾爱破解培训第一课作业一,自己自学了一段时间,最深也就是找到OEP,其实后面怎么做是不知道的,飞快地摆渡了下,刷刷就学会了 好像是转储将程序在内存的image储存到磁盘里来
找OEP是很容易的,下个硬件断点就到了.如图:
转储失败了好几次,后来看了帖子的作业解答部分,说是ASLR基地址随机化引起的,我记起了前不久,在书上有看到,直接修改PE文件中IMAGE_NT_HEADERS中的IMAGE_OPTIONAL_HEADER中的DLL Characteristics由8140改为8100,就可以让PE文件加载时不起用ASLR了,但我不知道这样是不是可以,我试了下,幸运的成功脱壳了,能正常运行.(刚刚我又将脱壳后的文件由8100改为8140,改完后,文件运行报错...)(我猜想这和专储原理机制有关系,但一时半会是不会去学习, 先放在一边捂脸)吃饭去
终于修复好了 作业三的破解版太曲折了还好有ximo脱壳基础 想完成第一课的作业三请观看ximo脱壳教程 第4课第一次学习还是看视频靠铺...容我休息一下 再战 今天看的是第二课直播和重录都看了一遍..真的好长啊啊啊 开这个帖子的目的是记录自己飞快地成长过程
说下我自己是如何完成第二课作业一的:
拿到作业一 我的第一反应是关闭动态基址;然后放到OD中开始脱壳(说起来好像在装比,但是我一般都不看是什么壳,直接手动脱,随机应变,现在的经验是绝大部分都能脱下来)
一进去就看到pushad 当然是使用esp守恒法, 跳到了OEP,用插件脱下来,迅速双击下看能成功运行不,能;
打开刚脱掉的程序,(注意不要运行到其他段去。。。)搜索字符串,发现http://www.52pojie.cn双击进入代码区位置 发现位于一个函数中部, 猜测应该是锁主页的功能,将函数最上面的push esp改称retn复制到可执行文件,保存文件测试通过(现在说的这么轻巧。。 我就是在这里坑了之前一直断点reg相关的api巨尴尬试了很久失败了最后想起搜字符串,才过得)
然后通过Restorator 将广告框不可视,找到 http://www.52pojie.cn/portal.php在数据区的位置 用00替换
断点WinExec把 http://www.52pojie.cn/forum-5-1.htm这个弹窗干掉
断点CreateProcessA 把http......68-1.htm这个弹窗干掉这时还剩下最后右下角的那个小广告了
DialogBoxParamW跟踪到右下角小广告线程起来的时刻, 稍微看下函数你发现当前函数起了两个线程 ,估计一个是右下角的小广告,一个是68-1.htm这个窗口 不管跑到函数最前面 将push esp 改成 retn 结束
不敢相信的是, 我为了写这个评论从零到完成又走一遍 居然花了我一个小时左右捂脸本来还想筛下截图的..发现我做不到...{:300_968:}明天可以开始第三课了第二课的作业二 有空做做 捂脸{:300_969:} 现在来练习下第四课的内容,打算做完第四课的例子,自己另外再找个论坛里的软件破解练练手. 教学视频好长... 直播加补充整整两个小时多...{:300_944:} 谢谢前辈们的无私分享
开始练习,首先我找标志是否注册的象征字符串"已注册版本" 找到函数位置在最上面push esp断点,Ctrl+F2 重新加载这个程序,点击注册出发我们刚下的断点(汇编指令还不是很熟悉,需要经常搜索摆渡)
00541870|.803D 249F5700>cmp byte ptr ds:,0x0
00541877|.74 10 je short qqqf.00541889
00541879|.BA F4185400 mov edx,qqqf.005418F4 ;已注册版本
0054187E|.8B83 FC020000 mov eax,dword ptr ds:
00541884|.E8 F77CFBFF call qqqf.004F9580
00541889|>33C0 xor eax,eax
现在00541877处的je是被触发了,显然我们不能让它触发,我把上面的0x0改为0x1.另存为保存起来
这个时候你测试一下,发现插入其他出现乱码,我们按照视频里的在按钮事件API上下断点,跟踪进去看看
点击插入昵称,停在了0048B2D6处,F7进入(这个时候我想万一程序验证起验证码了 怎么办,于是在注册页面填上1122334455667788,这样在调试中看到自己也容易明白,是在验证我输入的验证码),重复左侧操作到达0048B2D6处,F7进入 然后就是一个个观察。。。
在004B2E3D处 出现ASCII "xxx\qqf.exe" 高度警惕起来
接下来的call就要各种仔细跟进了,004B1F4F检查了下源程序qqf.exe是否存在, 看着看着 出现了一些ASCII数字,但是明显不是我输入的。。。 我怀疑是原文件的md5值得部分。。。 我得去弄个md5校验工具来看下源程序的md5值。。。 卒。。。 已经蒙了。。。再看下小生老师补充的那个视频。。。 第一次失败告终。。。
开始第二次尝试破解第四课例子:
首先搜关键词"未注册",发现没有,改为搜“注册”再搜寻有用信息,发现重要线索“已注册版本”,跟进去,在上指令上面一些打上断点,或者直接在这个函数头打断点也行,
然后发现能不能显示“已注册版本”,关键在于cmp byte ptr ds:,0x0,这句的比较,在第一次尝试破解的时候,我天真地以为只要将其结果变成不相等(将常量0x0改为了0x1),就可以了;
实际上是并不行的,首先软件开发者不太可能只在一个地方进行这个已注册未注册的验证,更理性的方式应该是分析变量的来源(就是0x579F24里面的值是什么时候被赋值的),我们查找所有常量0x579F24,给所有结果打上断点;
Ctrl+F2重新调试,点击运行,发现停在了一个断点处,
00541634 .8B0485 2C9F57>mov eax,dword ptr ds:
0054163B .E8 842FECFF call qqqf.004045C4
00541640 .83F8 18 cmp eax,0x18
00541643 .74 09 je short qqqf.0054164E
00541645 .83F8 0C cmp eax,0xC
00541648 .74 04 je short qqqf.0054164E
0054164A .33D2 xor edx,edx
0054164C .EB 02 jmp short qqqf.00541650
0054164E >B2 01 mov dl,0x1
00541650 >8815 249F5700 mov byte ptr ds:,dl
断点停在00541650,观看下上面的指令,可以大概猜出是比较一个长度是不是0x18和0xC,如果是,就将0x579F24的值赋值为1,我们F8一步步往下调,发现下面还有两个关于0x579F24的断点
不知道判断了什么又给0x579F24赋值,并且马上对0x579F24进行了比较cmp!,发生cmp 说明可能是有重要的分支要出现了,这个时候0x579F24应该必须赋值为1,才不会错过我们想要的。
00541695 .40 inc eax
00541696 EB 04 jmp short qqqf.0054169C
00541698 >33C0 xor eax,eax
0054169A .EB 02 jmp short qqqf.0054169E
0054169C >B0 01 mov al,0x1
0054169E >A2 249F5700 mov byte ptr ds:,al
005416A3 >803D 249F5700>cmp byte ptr ds:,0x0
我直接将00541696的条件跳转改称了无条件jmp跳转,然后你发现已经成功的注册了,现在软件弹出网络验证错误
搜索"正在验证" retn掉整个函数,然后重新打开,左下角显示已注册;然后尝试功能,发现插入昵称是乱码,我们得跟进去,由于这个程序是Delphi 写的,下Delphi 按钮断点,论坛里有人分享了这个脚本,大家可以搜一下,选择插入昵称跟进去,停在一个call上,F7进入;
00568198/.55 push ebp
00568199|.8BEC mov ebp,esp
0056819B|.6A 00 push 0x0
0056819D|.6A 00 push 0x0
0056819F|.33C0 xor eax,eax
005681A1|.55 push ebp
005681A2|.68 F4815600 push qqqf.005681F4
005681A7|.64:FF30 push dword ptr fs:
005681AA|.64:8920 mov dword ptr fs:,esp
005681AD|.8D4D F8 lea ecx,
005681B0|.33D2 xor edx,edx
005681B2|.B8 20000000 mov eax,0x20
005681B7|.E8 04ACF4FF call qqqf.004B2DC0
005681BC|.8B55 F8 mov edx,
005681BF|.8D45 FC lea eax,
005681C2|.E8 11CAE9FF call qqqf.00404BD8
005681C7|.8B45 FC mov eax,
005681CA|.50 push eax
005681CB|.E8 9046FFFF call qqqf.0055C860
005681D0|.5A pop edx ;qqqf.0048B2DC
005681D1|.E8 DAF6F8FF call qqqf.004F78B0
005681D6|.33C0 xor eax,eax
005681D8|.5A pop edx ;qqqf.0048B2DC
005681D9|.59 pop ecx ;qqqf.0048B2DC
005681DA|.59 pop ecx ;qqqf.0048B2DC
005681DB|.64:8910 mov dword ptr fs:,edx
005681DE|.68 FB815600 push qqqf.005681FB
005681E3|>8D45 F8 lea eax,
005681E6|.E8 EDC0E9FF call qqqf.004042D8
005681EB|.8D45 FC lea eax,
005681EE|.E8 1DC8E9FF call qqqf.00404A10
005681F3\.C3 retn
005681F4 .^ E9 23BAE9FF jmp qqqf.00403C1C
005681F9 .^ EB E8 jmp short qqqf.005681E3
005681FB .59 pop ecx ;qqqf.0048B2DC
005681FC .59 pop ecx ;qqqf.0048B2DC
005681FD .5D pop ebp ;qqqf.0048B2DC
005681FE .C3 retn
如上代码,马上映入眼前。。。我觉得这里可以采用一个BFS搜索算法的原理,先看下这6个call,发现只有第一个call 才有可能会实现一些检验等复杂的功能,我们跟进第一个call,饿,更多了call出现了;
首先我感觉可以下合理的猜测,就是检验应该是在SendMessageA这个系统API之前,因为这个是发送消息的功能部分,其实大多数在这种情况下,我们都有一种生死不自知的感觉。不过我偶然看论坛里,有人提到一个快捷方式,就是知道要进行md5校验,我们可以在和md5相关的API上下断点,更加迅速的靠近我们的目标位置,我选择GetFileSize,我准备试试,在开始之前在SendMessageA这里打上断点,想证明下上面自己的猜测对不对(如果GetFileSize在SendMessageA前面断下来了,说明我的猜测是对的);
Ctrl+G 搜索GetFileSize函数,并下断点。然后F9运行,停在了GetFileSize这里,证明我上面的这一小点推测是正确的。栈里面显call来自004B1E99,我们跳过去,发现了很多系统dll的api ,一步步F8,直到过了API CloseHandle,目标肯定在下面。
当我跟着程序走的时候,发现中途跳过了好几个call(使用retn的方式)
找到了md5比较处,虽然我怀疑,但是我反复确定 才真的确定下来(我察看了ebp-0x14发现是现在程序的md5值,脑袋里还是有昨天视频里的一点影像。。)
我发现这里的特点是将刚计算出来的文件md5值进行比较(这个md5就极大概率是保存在栈上了),md5这么长,比较起来肯定是有个小循环之类的
004B1F6F|.BE 10000000 mov esi,0x10
004B1F74 8D5D EC lea ebx,dword ptr ss:
004B1F77 8D55 E8 lea edx,dword ptr ss:
004B1F7A|.33C0 |xor eax,eax
004B1F7C|.8A03 |mov al,byte ptr ds:
004B1F7E|.E8 35F1FFFF |call qqqf.004B10B8
004B1F83|.8B55 E8 |mov edx,
004B1F86|.8BC7 |mov eax,edi
004B1F88|.E8 3F26F5FF |call qqqf.004045CC
004B1F8D|.43 |inc ebx
004B1F8E|.4E |dec esi
004B1F8F|.^ 75 E6 \jnz short qqqf.004B1F77
004B1F91|.33C0 xor eax,eax
004B1F93|.5A pop edx ;0012FCAC
查找二进制字符串 找到空白位置
最后 添加的代码为:
0056B0A8 BE 10000000 mov esi,0x10
0056B0AD C745 EC 11EA7>mov dword ptr ss:,0xA370EA11
0056B0B4 C745 F0 C3735>mov dword ptr ss:,0x295C73C3
0056B0BB C745 F4 B4855>mov dword ptr ss:,0x775285B4
0056B0C2 C745 F8 67564>mov dword ptr ss:,0x6A405667
0056B0C9 8D5D EC lea ebx,dword ptr ss:
0056B0CC 8D55 E8 lea edx,dword ptr ss:
0056B0CF 33C0 xor eax,eax
0056B0D1 8A03 mov al,byte ptr ds:
0056B0D3 E8 E05FF4FF call qqqf.004B10B8
0056B0D8 8B55 E8 mov edx,dword ptr ss:
0056B0DB 8BC7 mov eax,edi
0056B0DD E8 EA94E9FF call qqqf.004045CC
0056B0E2 43 inc ebx
0056B0E3 4E dec esi
0056B0E4 ^ 75 E6 jnz short qqqf.0056B0CC
0056B0E6 33C0 xor eax,eax
0056B0E8 5A pop edx ;0012FCAC
0056B0E9 ^ E9 A66EF4FF jmp qqqf.004B1F94
原来修改的地方为
004B1F5F|.E8 7423F5FF call qqqf.004042D8
004B1F64|.8D55 EC lea edx,
004B1F67|.8B45 FC mov eax,
004B1F6A|.E8 69FEFFFF call qqqf.004B1DD8
004B1F6F E9 34910B00 jmp qqqf.0056B0A8
004B1F74 8D5D EC lea ebx,dword ptr ss:
004B1F77 8D55 E8 lea edx,dword ptr ss:
004B1F7A|.33C0 |xor eax,eax
004B1F7C|.8A03 |mov al,byte ptr ds:
004B1F7E|.E8 35F1FFFF |call qqqf.004B10B8
004B1F83|.8B55 E8 |mov edx,
004B1F86|.8BC7 |mov eax,edi
004B1F88|.E8 3F26F5FF |call qqqf.004045CC
004B1F8D|.43 |inc ebx
004B1F8E|.4E |dec esi
004B1F8F|.^ 75 E6 \jnz short qqqf.004B1F77
004B1F91|.33C0 xor eax,eax
004B1F93|.5A pop edx ;0012FCAC
004B1F94|.59 pop ecx ;0012FCAC
004B1F95|.59 pop ecx ;0012FCAC
004B1F96|.64:8910 mov dword ptr fs:,edx
11EA70A3 C3735C29 B4855277 6756406A是qqqf.exe在我电脑上的md5值,尝试了下修改的文件 果然成功了 啊哈 吃小米饭去{:300_958:}
本帖最后由 间望 于 2017-7-29 11:19 编辑
第五课
看了前辈的课,我感觉重起验证的关键是程序会以某种方式先将key保存起来,然后重起的时候,在某个过程进行检验;
前辈说到了三种存储方式:
1.直接存到文件里
2.直接存在配置文件里(我对于配置文件使用到的API略有吃惊。。。在这之前 我以为是我们常见的那种打开文件的API。。。没想到这种配置文件原来有这种独特之处)
3.存放在注册表里
来看作业,刚开始蒙蔽了很长时间,怎么填内容都没任何反应。。。我还以为是点击按钮,就将我们输入的内容保存进去了,然后我又自己重起程序,监听了注册表相关函数。。。后来我搜了下论坛,发现有帖子说
输入的格式是详详细细xxxxxx-xxxxxxx-xxxxxxx分别保存到文件、配置文件、注册表。。。我才算正式开始,给函数CreateFileA、GetPrivateProfileStringA,RegOpenKeyA下断点
文件里的注释又清晰的显示出来。是ITN3UXJGJ
配置文件里,首先对长度进行的筛选,要求14位,过了这个条件后,就会进行比较,你会在内存里发现这部分key的未解秘状态(11223344556677是我输入的值)
0012F2CC3A 1E 02 25 28 1A 48 15:%(H
0012F2D43A 1D 02 25 28 1A 00 00:%(..
0012F2DC31 31 32 32 33 33 34 3411223344
0012F2E435 35 36 36 37 37 00 00556677..
在比较的时候,会将key的ASCII值加个0x30 再和你比较,所以真正的key,应该是内存里的key每位都加上0x30就是的,结果是jN2UXJxEjM2UXJ
注册表那部分可以说又更复杂一点点,它首先也对长度有个限制,但是这限制有些奇怪,我试了好几个长度 发现12和9是可以的,使用值333322221111继续跟进去(我写评论的时候,摆渡去查找相关线索,我现在觉得这里的长度限制可以这样确定,假设这个长度用L表示,限制的表达式是:(L+6)/5的商要等于3)
004022D3|.8A95 F8FEFFFF mov dl,byte ptr ss:
004022D9|.8D70 10 lea esi,dword ptr ds:
004022DC|.0FBE85 F4FEFF>movsx eax,byte ptr ss:
004022E3|.0FBECA movsx ecx,dl
004022E6|.48 dec eax
004022E7|.89B5 E4FEFFFF mov ,esi ;吾爱破解.0058E5F0
004022ED|.3BC1 cmp eax,ecx
004022EF|.75 69 jnz short 吾爱破解.0040235A
004022F1|.0FBE85 FCFEFF>movsx eax,byte ptr ss:
004022F8|.83C1 02 add ecx,0x2
004022FB|.3BC8 cmp ecx,eax
004022FD|.75 5B jnz short 吾爱破解.0040235A
004022FF|.80F2 54 xor dl,0x54
00402302|.80FA 66 cmp dl,0x66
00402305|.75 53 jnz short 吾爱破解.0040235A
这段代码你跟到内存去看数据加上指令逻辑分析,可以依次得出:key的第一位比第五位大1,第五位比第九位小2,第五位的ASCII是32,也就是2
接下来就是看起来很恐怖的循环了,前辈又很友好的在注释里,标记出关键值MjM、UXJ,再加上一个常量0x3被push进call的参数,(第一位和第五位中间也缺三位)我F7一进去,我就猜是不是看key里面存不存在MjM,
然后我就把3MjM2UXJ4试了下,果然通过了 {:300_958:} (修改:我在3MjM2UXJ4后面加任意4位以内的任意符号,发现都符合要求啊哈,这就是我们常见的bug么 ) 第六课...
我没想到第六课,会讲第五课的作业...
当我看到第六课的时候,我才发现,在第五课作业中,我其实一开始就是失败的{:300_944:}
我没有成功找到按钮事件的代码位置,是从论坛里,看到一个网友的帖子 提到格式是xxxx-xxxxx-xxxxx
其实如果我再仔细一点看搜索里的字符串的话,就可能会发现"注册成功,请重起程序",然后断过去
(当时我在输入框里,各种输入,毫无任何提示捂脸 , 有种蒙蔽的感觉,按第一直觉搜按钮上的文字,没有...)
我现在觉得 如果我们猜测到是重起验证, 最靠铺的应该是断PostQuitMessage,毕竟 字符串也是可以被加密的...
第六课作业很简单,将作业.exe放到OD里,先运行一遍,尝试一次(这样可以让程序的解密操作完成),然后CTRL+G跳到00401000附近,智能搜索,剩下的就和老师讲的是一样的
(刚开始,我还想脱壳来的... 就像以前讲的那样也不查壳,直接脱....脱了5次左右.这回终于撞南墙上了...发现自己脱不了 震惊到我了..拿exeinfope一查饿 看到了VMProtect v.2.07这几个大字 ){:1_933:} 好像必须回帖一下才能出现在 这个板块的列表里...{:300_960:} 唉装比就这样无形中被挫败了{:300_968:} 第二个作业也很简单和第一个作业一模一样......不过却有些挫折,我开始把它想复杂了,居然没有看到那个很明显的OEP,在里面找了很久,但是我熟悉的OEP就两个,其实也比较模糊,因为心里总担心这回是我以前没有见过的OEP,总之边调,边对照那几个很不熟悉的OEP入口特征....(其实我的断点已经过了OEP....)试了两回后 ,又去摆渡了下OEP 怕吾爱的不全{:300_955:} 刚好第三个链接的名字是:哪位大哥能告诉我,在脱壳过程中,怎么知道就到OEP了呢, 就点进去看了下 有网友说大跳...一看到这 我感觉很有道理重新审视了下 第二个作业的程序, 发现我早已误入藕花深处... 原来在审核中......我还是太年轻了...{:300_961:}Hmily为什么最帅 难道是论坛创始人{:300_957:} 挽尊破零回复 我也来挽一个 场面好尴尬! 有点监介哈哈哈 这波逼没装好啊