从堆栈查找Kernel32.DLL基址

原理是这样的:

每个用户态进程的WinMain代码都是由启动代码(CRTStartup)调用的,而启动代码是kernel32.dll里的某个函数调用的,当然也可能没有WinMain和WinMainCRTStart之类的函数(如Delphi编译出的代码),但进程启动后,kernel32.dll中的一个的未知代码位置一定保存在堆栈里的,所以从顶往底测试堆栈里的元素,一定可以找到kernel32.dll的基址,写了一小段代码,在Win XP SP2,VC++ 6.0 SP5下测试通过,可以找到我机器上的kernel32.dll的基址是0x7C800000.
CODE:


#include <stdio.h>
#include <conio.h>
#include <windows.h>

DWORD GetKernel32(void)
{
DWORD TryAddr=0;
PIMAGE_DOS_HEADER pdos=NULL;
PIMAGE_NT_HEADERS pnt=NULL;
PIMAGE_EXPORT_DIRECTORY pied=NULL;
DWORD *pKernel=NULL;
int i=0;

PDWORD pEsp=(PDWORD)&pEsp;
BOOL bFound=FALSE;
do
{
  __try
  {
   TryAddr=*pEsp;
   
   for(i=0;i<4;i++)
   {
    TryAddr&=0xffff0000<<(i<<2);

    pdos=(PIMAGE_DOS_HEADER)TryAddr;
    pnt=(PIMAGE_NT_HEADERS)(TryAddr+pdos->e_lfanew);
   
    if(pdos->e_magic=='ZM'&&pnt->Signature=='EP')
    {
     pied=(PIMAGE_EXPORT_DIRECTORY)(TryAddr+pnt->OptionalHeader.DataDirectory[0].VirtualAddress);
     pKernel=(DWORD *)(TryAddr+pied->Name);

     //KERNEL32 or Kernel32
     if((*pKernel=='NREK'&&*(pKernel+1)=='23LE')||
      (*pKernel=='nreK'&&*(pKernel+1)=='23le'))
     {
      bFound=TRUE;
      break;
     };//end if pKernel

    }//end if pdos

   }//end for i
  }
  __except(1)
  {
   NULL;
  }
  pEsp++;
}while(!bFound);

return TryAddr;
}

int main(void)
{
printf("KERNEL32.DLL at:0x%.8X/n",GetKernel32());
return getchar();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值