|
|
|
探讨一下OD内存断点的具体实现原理!
不是这样的。触发异常时,检查访问的目标内存是不是自己的范围。如果是,恢复内存断点所在页面的原有属性,执行单步,在单步中,OD再次设置内存断点所在页面的属性。 |
|
[讨论]Make a debugger
可以的。 但和你的目的不符合。我的理解是你希望有调试器的情况下,可以优先坐沙发。debug port=0后,调试器就再也到不了。 如果这样的话,还不如自己写个调试器来调试目标程序好了。 |
|
[讨论]Make a debugger
重新看了一下,关键是看调试器如何处理的。比如:发现不是自己设置的断点就不处理的话,bugtrapper还是可以继续处理的,如果调试器接手处理的话,bugtrapper就不能处理了。比如VC去调试的程序,bugtrapper就不能处理了。 总的来说,调试器肯定是中断的沙发。bugtrapper的处理好像是用的类似SEH的方法。应该是坐在SEH的沙发上吧。 |
|
[讨论]Make a debugger
好像搞错了。我突然想起来,好像这个程序被调试后,bugtrapper就接不到中断了。要真正解决这个问题,可能还是要从驱动入手。 另外,SetUnhandledExceptionFilter等这种方法根本上是不行的,因为一个程序被调试时,最先得到消息的还是调试程序,只有调试程序处理完了,才会通知其他的处理程序。debugger坐在沙发上是没有办法改变的。关于调试的调用路径,我记得有本书讲的比较清楚,好像叫<Windows NT/2000 本机 API 参考手册>,里面讲到驱动中如何派发debug消息的,估计在驱动中入手就可以搞定吧。 |
|
[讨论]Make a debugger
BugTrapper是用来监视函数调用的一个工具,我自己就根据这个创意,以另外一种方法实现了监视函数调用的功能(题外话 )。下面就将我很久以前调查的东西share一下,希望对大家有点帮助。 在很早以前就知道,BugTrapper在要监视的函数的入口第一个BYTE上写上0xCC的指令。这就是让程序产生一个中断调试例外! 因为0xCC(int 3)产生的函数中断,又如何将中断恢复呢?而且,根本就没有调试程序在调试你的程序。BugTrapper又是如何得到的呢?原来,BugTrapper在监视程序时,也采用了DLL的介入方案,接受中断的程序并不是BugTrapper,而是介入的DLL接收了由于修改函数入口而产生的中断例外。 在BugTrapper的介入DLL中,将修改Windows的例外处理接口,使得程序产生例外时,首先跳到Dll的处理函数中,如果该例外的地址为BugTrapper监视的函数入口,就将函数入口的原来指令写回该处,并且,修改例外的CONTEXT参数,使得程序执行时产生单步执行的中断例外。这样,在单步中断的处理中,将该函数的入口指令再次改为0xCC,用来下一次的函数被调用时再次产生中断。 修改例外处理的方法是修改KiUserExceptionDispatcher的处理,将自己的函数地址写在KiUserExceptionDispatcher函数的入口,这样,产生例外时,系统内核将调用该函数,就可以转入自己的例外处理函数了,在自己的例外处理函数中,需保存原来函数的内容,并且在最后运行这些内容,最后跳到原函数中(注意:不是入口,因为入口的内容已经被修改)这种方法在微软的DETOURS包中就进行了详细的介绍。。。。 首先,接入NT的NTDLL.DLL,接管KiUserExceptionDispatcher函数的处理(用微软的Detour技术。将第一个处理例外的接口为自己的函数。)这样,就可以监视由int 3引起的调试中断。当产生中断时,判断是不是自己监视函数产生的中断,如果是,就进行处理!同时进行单步运行,在单步中断时重新设置断点。 我自己用这种方法进行过简单的验证,事实证明确实可行,但要作为一个程序,里面就有很多要考虑的东西了。由于接管了KiUserExceptionDispatcher函数,所以可以保证坐在沙发上了。(5-6年前的调查,现在不知道是不是过时了 ) |
|
[讨论]Make a debugger
看明白了,就是想在被调试程序中自己截获int3的中断,这样就不会给调试器机会了。当然,要让被调试程序有自己截获int3中断的能力,就要通过inject了。其实,确实有一个这样的软件是使用这种方法的。但不是通过SetUnhandledExceptionFilter这种方法的,如LS说的,这种方法根本不保险,要做就做沙发才行。我看过一个软件BugTrapper就是用这种方法的。不过BugTrapper只能在9X和2000下运行,因为在9X下用的是驱动实现,在2000下用的是修改执行代码的方式,我怀疑由于2000下用的修改执行代码在XP上没有对应好修改的代码(那时候XP还没有出来),所有不能用了。关于驱动我没有研究过,下面就说说在2000下的实现机制,大家可以扩展到XP以后的了。 |
|
[推荐]Microsoft & Borland 编程软件合集 DVD 完美者发布 HTTP
Microsoft Visual C++ 6.0 SP6 中文企业版 创天中文垃圾版吧。坚决不用这个垃圾版。 |
|
[原创]第一个CrackMe,测试抗爆破性
嘿嘿,这种只能对付新手,对高手而言,都是被秒杀的。。。 |
|
[原创]第一个CrackMe,测试抗爆破性
恩,ccfer的正解。看来只有使用 “暗桩无敌大法” 才行。 |
|
[原创]第一个CrackMe,测试抗爆破性
俺知道爆破的涵义,就是修改关键点。这里没有计算算法。真正的关键点在if(bRegister)上。你的那个只是让MessageBox出来而已,并没有找到真正的关键点。就是说暗桩没有被拔除。第一个版本没有明确显示是不是假破解,确实是我的Interface问题了。 当然,蛋蛋同学不屑出手,我也理解,就当说明给其他要练手的同学听了。 |
|
[原创]第一个CrackMe,测试抗爆破性
另外,蛋蛋同学出手很快,就算是伪破解的版本,也是出乎我的预料,实在是佩服得很。 |
|
[原创]第一个CrackMe,测试抗爆破性
不是常量。是这样的: 比如: 初期化:a = 100; 然后在判断注册的地方: if(bRegister) a += 550; else a+= 500; 这样的话,如果没有找到if(bRegister)的爆破点,在软件中使用时就可以随时使用if(bRegister)进行控制程序的逻辑,出现伪破解。 |
|
[原创]第一个CrackMe,测试抗爆破性
希望被爆破的结果是: if(TRUE) a = 650; else a = 600; 而不是: if(bRegister) a = 650; else a = 650; 等待专家出手。 |
|
[原创]第一个CrackMe,测试抗爆破性
计算结果和注册码没有关系的。其实就像这样的: if(bRegister) a = 650; else a = 600; 这个是可以爆破的吧。 这里只有三个结果,Good - 650 成功 Error - 600 错误 Good - 600 伪破解 |
|
|
|
[原创]第一个CrackMe,测试抗爆破性
呵呵,被秒破了。我看了一下,是伪破解,我的关键代码都没有被运行。只是把OK的MessageBox弹出来而已。 这样的话,我的密码验证等很多程序就没有被执行。就是说,如果用到程序里面的话,到后面的计算结果就全部不对了。 |
|
[求助]如何读取当前文件夹下的ini文件?
那只能说是RPWT了。 另外,你的程序: success = WritePrivateProfileString("帐号资料", "ID", UserName.Text, "sgyscfg.ini") success = WritePrivateProfileString("帐号资料", "PW", PassWord.Text, "sgyscfg.ini") Private Sub Form_Load() Dim ret As Long Dim buff As String buff = String(255, 0) ret = GetPrivateProfileString("帐号资料", "UserName", "", buff, 256, "sgyscfg.ini") UserName.Text = buff buff = String(255, 0) ret = GetPrivateProfileString("帐号资料", "PassWord", "", buff, 256, "sgyscfg.ini") 写的是ID,读的是UserName,怎么可能拿到啊。 |
|
[求助]如何读取当前文件夹下的ini文件?
另外,是app.path +"\your.ini" !!!! |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值