從堆棧尋找Kernel32.DLL基址

來源:互聯網
上載者:User

原理是這樣的:

每個使用者態進程的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();
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.