• 【旧文章搬运】加载PE文件时IAT的填充时机


    原文发表于百度空间,2011-06-20
    ==========================================================================

    大致过程如下:

    LdrInitializeThunk  //ring3线程第一次执行从这里开始

    ->LdrpInitialize

    ->_LdrpInitialize

    ->LdrpInitializeProcess // 如果不是该进程第一次调用,这里会变成LdrpInitializeThread,判断依据是PEB->Ldr是否被填充过

    ->LdrpWalkImportDescriptor //该函数是递归的。。。

    ->LdrpHandleOldFormatImportDescriptors 或 LdrpHandleNewFormatImportDescriptors

    ->LdrpHandleOneOldFormatImportDescriptor  或 LdrpHandleOneNewFormatImportDescriptor

    ->LdrpLoadImportModule(这里会调用LdrpMapDll加载导入表中的dll),然后调用LdrpSnapIAT

    ->LdrpSnapThunk

    ->LdrpGetProcedureAddress  //获取函数地址,进行填充

    以上全是ntdll中的函数,所以什么给GetProcAddress下断观察IAT填充根本是不靠谱的。

    系统断点ntdll!DbgBreakPoint是在LdrpInitializeProcess中执行完LdrpWalkImportDescriptor把IAT填充完毕后判断BeingDebugged标志有效才中断的,这时候IAT都已经填充完了,如果用OD的话最早只能中断在系统断点,所以OD不能观察到这个过程。windbg调试程序时默认也是中断在系统断点ntdll!DbgBreakPoint,但是通过设置我们可以让windbg在收到进程创建事件时就中断下来,这时进程的第一个线程才刚刚从ring3开始执行,这样就可以提前给LdrpInitializeProcess和LdrpWalkImportDescriptor下断来跟踪IAT的填充过程。具体方法如下:

    一、用windbg打开要调试的PE文件,这时windbg会中断在ntdll!DbgBreakPoint

    二、选择"Debug"菜单里的"Event Filters",会打开以下对话框:


    然后把"Create Process"事件由Ignored设置为Enabled就可以了。

    三、在windbg命令窗口中输入".restart"来重启应用程序,这时就会中断在ntdll!KiUserApcDispatcher处

    四、给LdrpInitializeProcess和LdrpWalkImportDescriptor下断,然后g就可以在这里中断下来了

    因为很少用windbg调ring3程序,所以误以为不能比ntdll!DbgBreakPoint更早地中断,特此更正。

  • 相关阅读:
    仿微博添加和删除的动画
    到公司实习一个月记
    写一份好简历
    排序算法之快速排序
    PHP和MYSQL中的日期和时间
    我的php经历
    新的征程
    毕业设计笔记
    排序算法之总结
    javascript执行效率小结
  • 原文地址:https://www.cnblogs.com/achillis/p/10183748.html
Copyright © 2020-2023  润新知