IDA调试so_精细版_aihakcer
- 格式:pdf
- 大小:599.75 KB
- 文档页数:5


IDA 6.1调试驱动By obaby火星信息安全研究院今天在测试的时候发现IDA 5.5可以启动windbg调试器,而IDA 6.0却无法启动windbg 调试器。
大体看了一下可能是由于搜索路径造成的,重新将windbg安装到program files下之后问题就结局了。
网上也有关于用IDA调试驱动的文章,这里只是再整理一下,用IDA载入驱动分析完成之后选择调试器为Windbg debugger,如图1所示:图1然后执行菜单中的Debugger->Debugger options打开如图2所示的设置窗口。
图2点击Set specific options打开特殊选项窗口,如图3所示:图3将最上方的默认user mode修改为Kernel mode debugging 或者kernel mode debugging with reconnect and initial break,至于两个选项的区别读者可以自行测试一下,这里就不说废话了,按照字面意思理解即可。
设置完成后关闭设置窗口,然后执行菜单中的Debugger->Process options打开进程选项设置窗口,在Connet string中输入要连接的字符串,也就是com接口的名称,这里是com:port=\\.\pipe\com_1,baud=115200,pipe,如图4所示。
图4设置完成后关闭设置窗口,执行菜单中的Debugger->Attach Process,打开进程附加窗口,如图05所示。
图5附加之后等待符号库加载完就可以进行调试了。
调试器挂在之后如果没有意外会中断在第一个int3断点,如图6所示。
图6现在就可以对驱动进行设置断点和调试了,效果如图7所示:图7在调试之前为了使程序的断点能够中断需要修正Process options选项中的部分参数,如图8所示。
图8需要将Application修改为程序在远程目标机器上的路径,另外Directory同样需要修改为远程系统的目录。
IDA调试内核By obaby火星信息安全研究院以前总想知道IDA是否能够实现内核调试,后来找了一段时间没什么结果就暂时放弃了。
今天在国外的一个博客上偶然看到了用IDA实现内核调试的方法,其实现在国内也有很多文章介绍了IDA通过串口进行调试的文章,如果大家想看的话可以搜索下。
这里只是参考原文把实现的方法大体的用中文表述了一下。
在调试之前需要安装如下的软件:1.IDA PRO这个我想大家都应该有了;2.Windbg如果调试过驱动或者系统内核的话这个东西也应该有了;3.VirtualKd 这个东西我想大家如果没有做过使用IDA调试内核的话这个东西应该是还没有。
安装VirtualKD首先从官方网站上下载VirtualKd。
将程序解压到任意目录下,将程序目录下的Target 文件夹拷贝到虚拟机系统中运行(如果是VirtualBox则安装比较麻烦),运行之后将会出现如下的界面:点击Install之后将会在系统的启动菜单中创建一个新的启动项,如下图所示:如果使用设置Windbg调试器的方法来设置pipe在使用IDA调试的时候是无法正常连接调试器的(话说这个东西我测试了好久,囧)。
另外如果不使用上面的工具进行安装设置启动项的话可以手工设置,不过过程比较繁琐:1)拷贝kdvm.dll到你的客户机系统的system32目录下,在这个目录下应该可以找到KDCOM.DLL 和KD1394.DLL文件;2)打开并且编辑boot.ini文件添加一项新的启动项如下:multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional"/noexecute=optin /fastdetect /DEBUG /DEBUGPORT=VM如果是windows vista或者win7 则需要手工执行bcdedit命令来激活kdvm.dllbcdedit /set dbgtransport kdvm.dl3)重新启动虚拟机并且运行vmmon.exe进行监视。
环境搭建使用windows下面的ida pro 6.6调试Linux下面的程序需要使用ida的远程调试功能。
首先将ida文件夹中的dbgsrv/linux_serverx64文件放入需要调试程序的同级文件夹中。
再使用chmod a+x linux_serverx64 改变该文件的权限。
运行linux_serverx64打开IDA,选择Debuger->Run->Remote Linux Debugger点击ok就可以进行远程调试了。
反汇编分析首先我们需要找到main函数(前面的是数据初始化过程,不是写的函数的部分)然后进入的就是client程序反编译出来的汇编代码.text:00000000004008C6 push rbp.text:00000000004008C7 mov rbp, rsp.text:00000000004008CA sub rsp, 840h //提升堆栈.text:00000000004008D1 mov rax, fs:28h.text:00000000004008DA mov [rbp+var_8], rax.text:00000000004008DE xor eax, eax.text:00000000004008E0 mov rax, 2E302E302E373231h.text:00000000004008EA mov [rbp+var_820], rax //[rbp+var_820]为2E302E302E373231h.text:00000000004008F1 mov [rbp+var_818], 31h //[rbp+var_818]即为31h.text:00000000004008FA mov edx, 0 //0.text:00000000004008FF mov esi, 1 //SOCK_STREAM.text:0000000000400904 mov edi, 2 //AF_INET.text:0000000000400909 call sub_4007B0 //调用socket(AF_INET,SOCK_STREAM,0)函数.text:000000000040090E mov [rbp+var_838], eax //局部变量[rbp+var_838]就是sockfd.text:0000000000400914 lea rax, [rbp+var_830].text:000000000040091B mov edx, 10h //sizeof(struct sockaddr_in).text:0000000000400920 mov esi, 0 //0.text:0000000000400925 mov rdi, rax //rax = [rbp+var_830] 即一个局部变量 struct sockaddr_in servaddr.text:0000000000400928 call sub_400740 //调用memset(&servaddr,0,sizeof(servaddr))函数.text:000000000040092D mov [rbp+var_830], 2.text:0000000000400936 mov edi, 1F40h //0x1f40 = 8000 可见端口为8000.text:000000000040093B call sub_400710 //调用htons.text:0000000000400940 mov [rbp+var_82E], ax //将转换后的端口号保存到[rbp+var_82E].text:0000000000400947 lea rax, [rbp+var_830] //rax = [rbp+var_830] 即一个局部变量 struct sockaddr_in servaddr .text:000000000040094E lea rdx, [rax+4].text:0000000000400952 lea rax, [rbp+var_820] //[rbp+var_820]为2E302E302E373231h.text:0000000000400959 mov rsi, rax //rsi为[rbp+var_820]为2E302E302E373231h.text:000000000040095C mov edi, 2 //AF_INET.text:0000000000400961 call sub_400780 //调用inet_pton.text:0000000000400966 lea rcx, [rbp+var_830].text:000000000040096D mov eax, [rbp+var_838] //局部变量[rbp+var_838]就是sockfd.text:0000000000400973 mov edx, 10h //第三个参数大小.text:0000000000400978 mov rsi, rcx //第二个参数.text:000000000040097B mov edi, eax //第一个参数.text:000000000040097D call sub_4007A0 //调用connect函数.text:0000000000400982 mov edi, offset aSendMsgToServe ; "send msg to server: ".text:0000000000400987 call sub_4006F0 //调用 printf函数.text:000000000040098C mov rdx, cs:stdin@@GLIBC_2_2_5 //fget()的第三个参数stdin.text:0000000000400993 lea rax, [rbp+var_810].text:000000000040099A mov esi, 400h //字符串长度.text:000000000040099F mov rdi, rax.text:00000000004009A2 call sub_400770 //调用 fgets()函数.text:00000000004009A7 lea rax, [rbp+var_810].text:00000000004009AE mov rdi, rax //将内容设为参数给strlen().text:00000000004009B1 call sub_400700 //调用 strlen函数.text:00000000004009B6 mov rdx, rax //发送的信息的长度.text:00000000004009B9 lea rsi, [rbp+var_810] //发送的信息.text:00000000004009C0 mov eax, [rbp+var_838] //sockfd.text:00000000004009C6 mov ecx, 0.text:00000000004009CB mov edi, eax.text:00000000004009CD call sub_400720 //调用send()函数.text:00000000004009D2 lea rsi, [rbp+var_410].text:00000000004009D9 mov eax, [rbp+var_838] //将连接套接字赋给eax.text:00000000004009DF mov ecx, 0 //recv 最后一个参数.text:00000000004009E4 mov edx, 400h //接受大小.text:00000000004009E9 mov edi, eax //socket连接套接字.text:00000000004009EB call sub_4006E0 //调用recv函数.text:00000000004009F0 mov [rbp+var_834], eax //将recv接收到的内容保存给[rbp+var_834].text:00000000004009F6 mov eax, [rbp+var_834].text:00000000004009FC cdqe //转换DWORD(eax)成QWORD(rax).text:00000000004009FE mov [rbp+rax+var_410], 0.text:0000000000400A06 lea rax, [rbp+var_410] //此时的rax即为recv()函数接收到的东西.text:0000000000400A0D mov rsi, rax.text:0000000000400A10 mov edi, offset aReceivedS ; "Received:%s\n" //将这个字符串的地址给edi给后面打印函数传参.text:0000000000400A15 mov eax, 0.text:0000000000400A1A call sub_400730 //调用printf()函数.text:0000000000400A1F mov eax, [rbp+var_838] //将sockfd赋给eax.text:0000000000400A25 mov edi, eax //将sockfd赋给edi.text:0000000000400A27 call sub_400750 //调用close(sockfd).text:0000000000400A2C mov edi, 0.text:0000000000400A31 call sub_400790 //exit(0).text:0000000000400A36 db 2Eh.text:0000000000400A36 nop word ptr [rax+rax+00000000h].text:0000000000400A36 main endp ; sp-analysis failed验证猜想--更改发送内容1、首先定位到buf地址,由上述反汇编分析中可知,eax中的值为buf的地址。
IDA调试器的使用教程一、IDA调试器功能概述1.逆向工程:IDA调试器可以将二进制代码反汇编为易于理解的汇编语言代码。
这使得开发者可以更好地理解程序的功能,并可能发现其中的漏洞或隐藏的特性。
2.动态调试:IDA调试器允许用户在运行时监视和修改程序的状态。
用户可以设置断点、单步执行和查看寄存器和内存内容等。
3.静态分析:除了动态调试外,IDA调试器还提供了静态分析的功能。
用户可以直接在IDA中查看和分析反汇编代码,而无需运行程序。
4.插件支持:IDA调试器支持插件,用户可以根据需要安装并使用各种插件来增强IDA的功能。
5.导入导出:IDA调试器可以导入和导出多种文件格式,包括可执行文件、库文件和调试信息文件等。
二、IDA调试器使用步骤使用IDA调试器进行程序分析和调试通常包括以下步骤:1. 导入程序:首先,需要将目标程序导入到IDA调试器中。
可以通过“File -> Open...”来导入文件。
IDA会自动分析程序并在主窗口中显示反汇编代码。
2.动态调试:接下来,可以使用IDA调试器的动态调试功能来监视和修改程序的状态。
可以通过设置断点、单步执行、在特定条件下停止等方式来控制程序的执行。
3.内存和寄存器查看:在动态调试过程中,可以随时查看和修改内存和寄存器的内容。
IDA调试器会为用户提供一个交互式的窗口,以方便用户对内存和寄存器进行操作。
4.静态分析:如果需要对程序进行更深入的分析,可以使用IDA调试器的静态分析功能。
用户可以直接在IDA中查看代码,并使用IDA提供的各种功能进行反汇编代码的分析。
5. 插件扩展:如果需要进一步增强IDA调试器的功能,可以考虑安装适用于IDA的插件。
可以通过菜单栏上的“Edit -> P lugins”的选项来安装和管理插件。
三、实例演示:使用IDA调试器分析和调试程序以下是一个使用IDA调试器分析和调试程序的演示实例:1.打开IDA调试器并导入目标程序。