zoukankan      html  css  js  c++  java
  • windbg查找Kernel32.dll基址

    一、首先准备好一个程序,运行起来,用windbg进行附加调试,由于每个windows下的程序都会加载kernel32.dll,因此,找基址的过程是一样的;

     二、查看PEB地址;

    法一、r $peb

    法二、通过TEB获取,r $teb

    获取到teb地址后,对_TEB结构体解析dt _TEB 3ca000

     

    法三、通过fs寄存器获取,我们知道fs:[0]就是TEB结构体的首地址,但是,在windbg里dd fs:[0]时,地址却做了隐藏:

    那该怎么办呢,其实,这就要看下TEB的结构了

    在TEB结构的0x18偏移处,存放的其实就是TEB的地址,和fs:[0]是一样的;

    另外,在TEB结构的0x30偏移处,存放的就是PEB的地址,我们再来看下:

    和上面两种方法,得到的结果都是一致的,这也验证了我们的想法;

     三、接下来,既然PEB的地址找到了,就对PEB进行解析:

    首先找到LDR:

    接下来,解析LDR:

    这里,也许有人会有疑问:那个_LIST_ENTRY后面,怎么有两个值,是什么含义呢?加个-b,就看出来了:

    typedef struct _LIST_ENTRY {
       struct _LIST_ENTRY *Flink;
       struct _LIST_ENTRY *Blink;
    } LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;

    其实,内核数据结构中,比较常见,使用的这个双向链表;

    我们就选取InLoadOrderModuleList这个链;对它的Flink进行解析,

    通过查阅MSDN,知道,这个Flink指向的具体的数据结构类型是:_LDR_DATA_TABLE_ENTRY

    继续遍历InLoadOrderLinks的Flink字段:

    还不是Kernel32.dll,继续走:

    到此,通过遍历InLoadOrderLinks链,我们找到了KERNEL32.DLL,取出基址就比较容易了,在0x18偏移处;

    取出这个基址,我们就可以解析PE导出表,找到我们需要的函数的地址了;

    四、代码

    int GetKernel32Base() {
        int nAddress = 0;
        _asm {
            push eax;
            mov eax, fs:[0x30]; // PEB
            mov eax, [eax + 0xC] // LDR
            mov eax, [eax + 0xC] // InLoadOrderModuleList, exe
            mov eax, [eax]; // nt.dll
            mov eax, [eax]; // kernel32.dll
            mov eax, dword ptr ds:[eax + 0x18]; // BaseAddr;
            mov nAddress, eax;
            pop eax;
        }
        
        return nAddress;
    }

    附录:

    参考MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/aa813708%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

  • 相关阅读:
    sql developer Oracle 数据库 用户对象下表及表结构的导入导出
    安装Win7和Office2010并激活
    Python内置方法的时间复杂度(转)
    服务框架Dubbo(转)
    ntpd和ntpdate
    ntpdate server时出错原因及解决
    什么才是程序员的核心竞争力
    使用DNSPod来处理网站的均衡负载(转)
    ubuntu设置服务开机启动
    Linux运行级别
  • 原文地址:https://www.cnblogs.com/Reginald-S/p/8761150.html
Copyright © 2011-2022 走看看