逆向入门(42)程序逆向篇-riijj_cm_20041121
0x00 初试
一打开就带有一个dll
直接全部解压运行,发现点击也没有什么窗口提示,看了下也没壳,直接进调试器吧
在调试器中发现程序会直接结束程序运行
设置了忽略异常还是会存在这个问题,搞不好了,用了其他的办法,比如说用od
的插件strongOD
的设置也不行,但是查找一些资料的时候发现他们可以,原因未知,这个题真的是新人噩梦啊,不查资料根本没法做,于找了两篇资料来学习,也是看了很久,学到了。学习资料1、学习资料2
0x01 exe1
这里是有反调试器技术,嗯,原来游戏碰到都是通过其他人解决的,第一次自己动手处理,由于没有解决dbg
这个异常处理的问题,于是又用OD
来进行尝试,这里先关掉strongOD
里面的忽略异常
接着重新加载一下文件,按F9
报错了
此时按shift+f9
,虽然可以直接跳过这个异常,但是也会存在问题,左下提示调试器出错了,再按一次就退出了
所以再重新加载一次,用f8
步进吧,步进到这个地方的时候又异常了
给这里下个断,重新加载一次,然后断下来后,进入这个函数
一直步进,找到了异常的原因,jmp
到了一个空地址
其实在没有查资料的时候自己也找到这里来了,但是到这了就不知道应该怎么办了,想直接jmp
也不知道跳到哪,于是只能按资料里面的信息去查了上面一段代码中的SEH
AI
给的一段解释
根据资料的一些信息,这里SEH
会成为反调试技术还是因为利用了调试器不支持的一些技术原因,进入0x4024D0
即SEH
函数打下断点,取消之前的断点,重新再次加载
按shift+f9
,第一次进入到这个SEH
中,按F8
步进
到这个地址会再次报错异常,给这个地址打下断点,继续shift+f9
,观查寄存器的值
这里的ecx
会一直变化,指向到不同的函数,到这里的直接就按一下f7
,跟进去看看,持续到第5
次出现异常时进入到了新函数
不过回来以后还是异常了,接着跟
ECX
到了0x12
的时候,又进入到了新函数,也是卸载这个SEH
函数的地址,程序也停在这了,再来一次就中断了,所以就处理完这个卸载函数时,让他jmp
到之前程序处理异常的那个地址应该就可以了,也就是上图中的401940
函数,重新加载以后, 再次来到上图的位置,这次将401cf2
处的汇编改为jmp 0x00401940
打个补丁就可以
0x02 exe2
重新加载得到的新的exe
,但是仍然会退出程序,但是和上次不一样,在寄存器处有明显的提示
这个isDebuggerPresent
是官方用来检查测试器的一个函数,通过使用插件对刚刚的api
函数进行断点设置
这次在这里又出现了异常
将je
直接改jmp
强制跳转,然后再patch
一个新exe
。
0x03 exe3
再次运行后终于出现了窗口,但是这个窗口仍然卡在这个界面
再按两次shift+f9
就退出进程了,真是服啦,咋这难,接着学!
回到这个call
,下个断点,断下来的时候进入看看
发现这里一直在读进程相关信息,继续追一下,进入到401640
这里发现一直在遍历dll
文件
往下还看到了一个配置文件ollydbg.ini
读取某配置文件进行判断是否开了调试器吗,试了下x32dbg
,果然正常
服了,回到OD
再追一下
这里打个断点,一直在循环读取各种路径下的ollybdg.ini
,看看不跳的时候是不是会退出就知道了
多追了一下,突然就不跳了,奇怪的是我好像也没这个路径,不过不管了,直接将这里的je
改为jmp
以后再存一个exe4
,终于是不检测了,我的天,这明显是地狱难度啊
0x04 exe4写注册机
由于这个程序点击没有反应,所以使用GetWindowTextA
来进行下断点,但是没有断下来,后来想了一下,加载了dll
程序的,可能是搜索范围不对,于是点击E
,然后双击进入pdf1.dll
再次进行搜索,获得关键字
往上翻了下,就可以正常下断点了
找到计算算法如下
可以写出注册机,总算有个简单的内容了
#include <iostream>int main() {const char* checkStr = "fytugjhkuijonlbpvqmcnxbvzdaeqrwtryetdgfkgphonuivmdbxfanqydexzwztqnkcfkvcpvlbmhotyiufdkdnjxuzyqhfstae";char username[256] = { 0 };char serial[256] = { 0 };printf("用户名: ");std::cin.getline(username, 256);int nameLen = strlen(username);for (int i = 0; i < nameLen; i++){unsigned char temp = username[i] % 98;serial[i * 2] = checkStr[temp];serial[i * 2 + 1] = checkStr[temp + 1];}printf("serial: %s", serial);return 0;
}
搞定
真是难得没边了都,太不友好了!