有源码可以直接使用 模块+函数名断,没有源码只能断绝对地址,对于用户态进程,每个程序都有2G的虚拟地址空间,但对于内核,由于共享一块虚拟地址空间,所以不能根据PE文件偏移来断,只能想办法得到其绝对地址,配置好调试环境并且加载驱动以后,使用WinDbg命令 lm 可以列举出操作系统加载所有模块的信息,其中有加载的实际起始地址和终止地址(事前可能需要使用.reload重新加载一遍所有模块),如果模块过多可以使用m选项进行过滤。最后得到信息如下:
kd>lm m DriverName start end module name b21df000 b2200000 DriverName(deferred)
还可用过命令 !dh 命令查看 PE 格式信息,其中可以找出基址地址:
kd>!dh b21df000 File Type: EXECUTABLE IMAGEFILE HEADER VALUES 14C machine(i386)6number of sections 4CBB7B79timedatestamp Mon Oct1806:40:572010 0filepointer to symbol table0number of symbols E0sizeof optional header 10E characteristics Executable Line numbers
stripped Symbols stripped32bit word machine OPTIONAL HEADER VALUES 10B magic#7.10linker version19800sizeof code3400sizeof initialized data0sizeof uninitialized data 1A8DC address of entry point1000base of code-----new-----00010000 image base1000section alignment200filealignment
其中 image base 展示 PE 文件期望加载地址为 0x00010000,再通过IDA可以查看任意代码偏移,这个偏移实际上是相对0x00010000,通过简单的计算就可得出实际虚拟地址的位置。
比如一个函数位于 .text:000228D3 处,计算实际地址 = 偏移(0x000228D3)- 期望基址(0x00010000)+ 实际基址(0xb21df000),接下来可通过 bp address 下断。