这次拿三个问题来讨论,是关于调试器的。因为对于反病毒工程师而言,类似于OllyDbg和IDA的使用方法是必须掌握的,但是在面试中又不太方便考察,所以只能对其快捷键或者调试器实现原理之类的问题进行提问。这里我还是选取比较权威的书籍上的答案,免得仅仅提供我自己的答案会误导大家,也难有说服力。如果说大家以后在面试的时候遇到这些问题,只要回答出关键点就可以,无需一字不落地背下来。因为我摘录的答案的篇幅往往比较长,为的就是让大家更为全面地看待这个问题。

问题4——6如下:

4、在IDA中,快捷键X的作用是什么?什么是交叉引用?

答:(以下内容选自《加密与解密 第三版》第3.2.5节)

通过交叉参考(XREF)可以知道指令代码相互调用关系。如下面代码所示,这句“CODE XREF:sub_401120+B↑j”,表示该调用地址是401120,“j”表示跳转(jump)。其他一些符号:“o”表示偏移值(offset),“p”表示子程序(procedure)。双击这里或按回车键可以跳到调用该处的地方。

.text:00401165                    loc_401165:                ;CODE XREF:sub_401120+B↑j
.text:00401065 push 0 ;nExitCode
.text:00401067 FF 15 B0 40 40 00 call ds:PostQuitMessage</span>

在loc_401165字符上按X键,将打开交叉参考窗口。

(关于交叉引用更为详细的说明,可参考《IDA Pro权威指南 第2版》第9章——交叉引用与绘图功能)

 

5、请解释一下什么是DR寄存器。

答:(以下内容选自《IDA Pro代码破解揭秘》第6.2节)

要真正理解调试,了解各种中断及调试寄存器是很有必要的,特别是有关进程状态变化的。Intel Software Developers Manual在这方面依然是最好的参考资料,我知道的与它相比,不过是小巫见大巫。不过,IA-32平台处理调试基本上是通过二者(中断或调试寄存器)之一实现的。

首先介绍一下调试寄存器。IA-32平台有8个调试寄存器,最多可以监视4个地址。访问这些寄存器是通过mov指令(调试寄存器暗中充当目的操作数或源操作数)的变体实现的。要知道,访问这些寄存器是需要有RING0特权的,这当然是一个限制,但考虑其影响极大,这样做也是有道理的。对每一个断点,有必要具体指定涉及的地址、位置的长度(范围在一个字节与双字之间)、处理程序(当生成一个调试异常时)以及这个断点是否被启用。前4个调试寄存器,DR0到DR3可以包含4个32位地址(定义了断点应该出现的地址)。接下来的2个调试寄存器DR4和DR5取决于操作模式可以交替使用。当DE(Debugging
Extension,调试扩展)标志被设在CR4(Control Register4,控制寄存器4)里时,DR4和DR5保留,试图引用它们时,将引发一个无效操作码异常。如果这个标志没有被设置,DR4和DR5则作为别名替代调试寄存器6和7。

DR6(DebugRegister 6,调试寄存器6),作为调试状态寄存器指示对最后发生的调试异常进行条件检查的结果。用位模式访问DR6,位0到位3与前4个调试寄存器相关。这些位指示哪个断点条件被满足而生成了一个调试异常。DR6的位13在置位时表示下一条指令引用一个调试寄存器,连同DR7(我们随后就会介绍)的一部分被使用。位14对我们来说或许是最有诱惑力的,它被置位时指示处理器处于单步模式(single-step mode),我们稍后介绍。最后使用的是位15,它指示当调试陷阱标志被置位时,作为任何切换的结果都会抛出调试异常。最后,我们介绍调试寄存器7,也就是DR7。所有的黑客都对这个寄存器垂涎欲滴,它也被称为调试控制寄存器,像DR6一样被理解为位字段。这个寄存器的第一个字节对应断点是否是活动的,如果是活动的则对应它的作用域。位0、2、4和6确定调试寄存器是否被启用,位1、3、5和7对应同样的断点,但基于全局的作用域。在这个例子里,作用域被定义为在任务切换时断点是否保持,是否针对全局启用的断点对所有的任务都是可用的。根据Intel的手册,现在的处理器不支持位8和9。不过在以前,可以用它们确定引起断点事件的精确的指令。接下来是位13,这是一个比较有意思的位,它允许在访问调试寄存器本身之前中断。最后是位16到31,这些位确定什么类型的访问会引起断点,以及所在地址的数据长度。当CR4中的DE标志被置位时,位16到17、20到21、24到25、28到29被解释成下面的意思:

00 – Break onexecution

01 – Break onwrite

10 – Break onI/O read or writes

11 – Break onread and writes but not instruction fetches

当DE标志没有置位时,除了10的值没有定义以外,其他的解释同上面一样。位18到19、22到23、26到27、30到31对应各种断点的长度,值00表示长度为1,值01表示2字节长度。在32位平台上10未被定义,在64位平台上它表示8字节长度。你可能已经猜到了,11表示长度为4字节。

现在,把所有这些位与DR0至DR3联系起来似乎比较困难,但实际并不是这样的。每个2位组合对应DR0至DR3范围里特定的连续的寄存器。这些长度必须对齐某些边界(取决于它们的大小)——例如,16位需要以字为界,32位以双字为界。这由处理器通过掩码地址的低位相关地址来强制执行,因此,一个未对齐的地址将不会产生预期的结果。如果访问起始地址加上它的长度范围内的任意地址,将产生异常,通过使用2个断点有效地允许未对齐的断点;每个断点被适当地对齐,在它们两个之间包含了讨论的长度。这里还有一点值得一提。当断点访问类型只是执行时,应当把长度设为00,其它的值导致未定义的行为。

注意:有趣的是,调试寄存器本身并没有受到很多关注。不过,私下里还是有很多利用它们的rootkits和后门。比如说,可以在指向进程结构的指针上设置一个全局访问断点,在进程的链表里隐藏进程。当访问这个地址时,将出现调试异常,并重定向到它们的处理程序并执行任意多的任务,包括返回列表里下一个进程的地址。

更糟的是,它们可以启用DR7里的GD标志,并导致访问调试寄存器本身并引发异常,阻挠审查寄存器来检查它们当前的配置。

6、请说明单步执行分为哪几种,区别是什么,其实现原理是什么。

        答:(以下内容选自《IDA Pro代码破解揭秘》第5.2.2节)

单步是指每次执行一条指令,然后把控制权交给调试器的过程。IA-32系列处理器在硬件上直接支持单步。通过一次执行一条指令,我们可以仔细监视代码的特定部分。不过不太可能用这个方法调试整个程序。单步通常用于理解特定部分的代码。

从CPU的角度来看,调试器设置EFLAGS寄存器里的TF(Trap Flag,陷阱标志)位。一条指令执行完后就会生成调试异常,调试器会把这个调试异常当做中断(INT 0x01)捕获。

注意:大多数调试器都提供step(单步)命令。通常把他们称为步入(step into)和步过(step over)。从用户角度来看,它们之间唯一的不同是出现在某些指令上,其实就是call和rep指令上。当碰到call时,步入命令将跟随call,而步过命令将在call之后的指令上中断。这通常由设置断点来完成,而不是单步执行到返回。

        知识扩展:

(以下内容选自《加密与解密 第三版》第2.1.5节)

当执行一个INT 3断点时,该地址处的内容被调试器用INT 3指令替换了,此时OllyDbg将INT 3隐藏了,显示出来仍是下断前的指令,而实际上这个指令已经被替换成了CC。

这个INT 3指令,其机器码是CCh,也常称为CC指令。当被调试进程执行INT3指令导致一个异常时,调试器就会捕捉这个异常从而停在断点处,然后将断点处的指令恢复成原来的指令。当然,如果自己写调试器,也可用其他一些指令代替INT 3来触发异常。

用INT 3断点的好处是可以设置无数个断点,缺点是改变了原程序指令,容易被软件检测到。例如为了防范API被下断,一些软件会检测API的首地址是否为CCh,以此来判断是否被下了断点。在这用C语言来实现这个检测,方法是取得检测函数的地址,然后读取它的第一个字节,判断它是否等于“CCh”。下面这段代码就是对MessageBoxA函数进行的断点检测:

FARPROC Uaddr;
BYTE Mark = 0;
(FARPROC&)Uaddr = GetProcAddress(LoadLibrary("user32.dll"), "MessageBoxA");
Mark = *((BYTE*)Uaddr); //取MessageBoxA函数第一字节
if(Mark = = 0xCC) //如该字节为CC,则认为MessageBoxA函数被下断
return TRUE; //发现断点

程序编译后,对MessageBoxA设断,程序将会发现自己被设断跟踪。当然躲过检测的方法是将断点下在函数内部或末尾,例如可以将断点下在函数入口的下一行,就可以躲过检测了。

(以下内容选自《加密与解密 第三版》第15.3.7节——通过TrapFlag检测)

CPU符号位EFLAGS中一位叫做TF,即TRAP FLAG。当这个TF=1的时候CPU执行完EIP的指令就会触发一个单步异常。例如这段代码:

pushfd
push eflags
or dword ptr [esp],100h ;TF=1
popfd ;这条指令之后TF=1了
nop ;这一条执行后会触发异常,应该提前安装SHE,跳到其他地方执行
jmp die ;如果顺序执行下来了,说明被跟踪

本篇文章参考资料:

    1、段钢(主编),Blowfish、沈晓斌、丁益青、单海波、王勇、赵勇、唐植明、softworm、afanty、李江涛、林子深、印豪、冯典、罗翼、林小华、郭春杨(编委),《加密与解密(第三版)》,电子工业出版社。

2、[美]Chris Eagle(著),石华耀、段桂菊(译),《IDA Pro权威指南(第2版)》,人民邮电出版社。

3、[美]Dan Kaminsky、Justin Ferguson、Jason Larsen、Luis Miras、Walter Pearce(著),看雪论坛翻译小组(译),《IDAPro代码破解揭秘》,人民邮电出版社。

技术面试问题汇总第002篇:猎豹移动反病毒工程师part2的更多相关文章

  1. 技术面试问题汇总第001篇:猎豹移动反病毒工程师part1

    我在2014年7月1日参加了猎豹移动(原金山网络)反病毒工程师的电话面试,但是很遗憾,由于我当时准备不足,加上自身水平不够,面试官向我提出的很多技术问题我都没能答出来(这里面既有基础类的问题,也有比较 ...

  2. 技术面试问题汇总第005篇:猎豹移动反病毒工程师part5

    这是我当初接受面试的最后两个问题,当时,那位面试官问我对漏洞了解多少时,我说一点都不懂,问我懂不懂系统内核时,我同样只能说不知道.后来他跟我说,面试的考查重点不在于我所掌握的知识的广度,而是深度.这也 ...

  3. 技术面试问题汇总第004篇:猎豹移动反病毒工程师part4

    这次所讨论的三个问题,比如DLL以及HOOK,很容易被病毒木马所利用,因此必须要比较全面地进行了解.而异常处理机制,则往往与漏洞相关联.它们自身的概念并不难理解,只是由之引申而来的问题,在计算机安全领 ...

  4. 技术面试问题汇总第003篇:猎豹移动反病毒工程师part3

    从现在开始,面试的问题渐渐深入.这次的三个问题,都是对PE格式的不断深入的提问.从最初的概念,到病毒对PE格式的利用,再到最后的壳的问题.这里需要说明的是,由于壳是一个比较复杂的概念,面试中也仅仅只能 ...

  5. 【转】Java方向如何准备BAT技术面试答案(汇总版)

    原文地址:http://www.jianshu.com/p/1f1d3193d9e3 这个主题的内容之前分三个篇幅分享过,导致网络上传播的比较分散,所以本篇做了一个汇总,同时对部分内容及答案做了修改, ...

  6. Java方向如何准备BAT技术面试答案(汇总版)

    这个主题的内容之前分三个篇幅分享过,导致网络上传播的比较分散,所以本篇做了一个汇总,同时对部分内容及答案做了修改,欢迎朋友们吐槽.转发.因为篇幅长度和时间的原因,部分答案我没有亲自总结.更多精彩内容请 ...

  7. 【转载】Java方向如何准备BAT技术面试答案(汇总版)

    作者:微信公众号JavaQ链接:https://www.nowcoder.com/discuss/31667?type=0&order=0&pos=11&page=1来源:牛客 ...

  8. 【转】Java方向如何准备技术面试答案(汇总版)

    本文转载自:“Java团长”公众号 1.面向对象和面向过程的区别 面向过程优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机.嵌入式开发.Linux/Unix等一般采 ...

  9. Java方向如何准备技术面试答案(汇总版)

    本文转载自:"Java团长"公众号 1.面向对象和面向过程的区别 面向过程优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机.嵌入式开发.Linu ...

随机推荐

  1. C++入门(2):为何还学C++?

    本文首发 | 公众号:lunvey 提及编程语言,最近很火的当属Python和Java,似乎C++没落了,真的是这样吗? 转行做程序员,掌握一门编程语言,也就是职业技能,我相信更多的是在乎未来发展而不 ...

  2. POJ-1182(经典带权并查集)

    食物链 POJ-1182 一个很好的分析博客:https://blog.csdn.net/niushuai666/article/details/6981689 三种关系:两者同类,吃父节点,被父节点 ...

  3. MySql学习---数据库基本类型,事务,多表查询

    数据库分类 关系型数据库 行列, 列如Mysql,oracle 通过表和表之间,行和列之间的关系进行数据的存储 非关系型数据库: Redis,MongDb 以对象存储,同过对象的自身属性来决定 表与表 ...

  4. 优秀的vue服务端渲染框架

    目前国内优秀的基于vue的ssr框架有minissr,可以在服务端生成html代码,有利于搜索引擎爬取. https://www.wechatmini.com/vue/minissr 使用方法可以参考 ...

  5. FreeBSD 乃至开源界中的孔乙己 再论苦难哲学之一

    在许多狂热的FreeBSD 粉丝里,他们甚至不允许别人把FreeBSD写作freebsd,要和你强调,F和BSD都是大写的.还说这是什么尊重之类的东西.大抵和孔乙己的茴香豆的茴的有四种写法一样吧:&q ...

  6. VMware 虚拟机安装(使用CentOS镜像)

    (1)启动虚拟机,点击"文件"-->"新建虚拟机",选择安装类型,推荐"典型".       (2)选择稍后安装操作系统       ...

  7. apk动态调试

    android.os.Debug类提供了isDebuggerConnected()用于检测是否有调试器链接: AndroidManifest的application节点中加入android:debug ...

  8. 10 分钟轻松学会 Jackson 反序列化自动适配子类

    作者:丁仪 来源:https://chengxuzhixin.com/blog/post/Jackson-fan-xu-lie-hua-zi-dong-shi-pei-zi-lei.html json ...

  9. C 语言代码风格之 Linux 内核代码风格

    GitHub: https://github.com/storagezhang Emai: debugzhang@163.com 华为云社区:https://bbs.huaweicloud.com/b ...

  10. OCPC产品初探

    OCPC即Optimization CPC,今天我们就来看看它的Optimizaton在哪儿. 在广告模型初探(一)中我们就曾提到过,互联网广告的本质其实就是流量的买卖.是广告主.媒体方以及用户三方之 ...