一个IE补丁的原代码


// jscriptpatch.cpp
//==============================================================
// Patch for the IE createTextRange() vulnerability.
//
// Derek Soeder - eEye Digital Security - 03/24/2006

#define WIN32_LEAN_AND_MEAN

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



// TranslateRVAToRawPtr

PBYTE TranslateRVAToRawPtr(
 PBYTE   pbBase,
 DWORD   dwRVA)
{
 PIMAGE_NT_HEADERS ppe;
 PIMAGE_SECTION_HEADER psect;
 DWORD   dw;

 //----------------
 ppe   = (PIMAGE_NT_HEADERS)(pbBase + ((PIMAGE_DOS_HEADER)pbBase)->e_lfanew);
 psect = IMAGE_FIRST_SECTION(ppe);

 for (dw = ppe->FileHeader.NumberOfSections; dw != 0; dw--, psect++)
 {
  if (dwRVA >= psect->VirtualAddress && (dwRVA - psect->VirtualAddress) < psect->SizeOfRawData)
   return pbBase + (dwRVA - psect->VirtualAddress + psect->PointerToRawData);
 } //for(dw)

 return NULL;
} //TranslateRVAToRawPtr()



// CreateJScriptPatchDLL

BOOL CreateJScriptPatchDLL(
 char   *szOriginalDLL,
 char   *szPatchDLL)
{
 HMODULE   hmod;
 DWORD   cbmodsize;
 PIMAGE_NT_HEADERS ppe;
 PIMAGE_SECTION_HEADER psect;
 DWORD   dwsectnum;

 PDWORD   pdw;
 PVOID   pvend;
 DWORD   dw;

 DWORD   dwrva, dwrvadest;
 PBYTE   pb;
 LONG   lofs;
 DWORD   dwlen;
 BOOL   bebp;

 HANDLE   hfile;
 PBYTE   pbdest;
 DWORD   cb;
 DWORD   dwerr;

 //---------------- load the original DLL with virtual alignments and relocations applied
 hmod = LoadLibraryEx(szOriginalDLL, NULL, DONT_RESOLVE_DLL_REFERENCES);

 if (hmod == NULL)
  return FALSE;

 dwrva     = 0;
 dwrvadest = 0;

 //---------------- search for an executable section with sufficient unused space
 ppe = (PIMAGE_NT_HEADERS)(((PBYTE)hmod) + ((PIMAGE_DOS_HEADER)hmod)->e_lfanew);

 if (ppe->Signature != IMAGE_NT_SIGNATURE)
 {
  FreeLibrary(hmod);
  SetLastError(ERROR_INVALID_EXE_SIGNATURE);
  return FALSE;
 }

 psect = IMAGE_FIRST_SECTION(ppe);

 for (dwsectnum = 0; dwsectnum != ppe->FileHeader.NumberOfSections; dwsectnum++, psect++)
 {
  if ( (psect->Characteristics & (IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_DISCARDABLE|IMAGE_SCN_CNT_CODE)) !=
       (IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_CNT_CODE) )
  {
   continue;
  }

  if ( ((psect->Misc.VirtualSize & 0x0FFF) != 0) &&
       ((psect->Misc.VirtualSize & 0x0FFF) <= 0x1000 - 0x20) && // patch code will be <= 0x20 bytes
       (psect->SizeOfRawData > psect->Misc.VirtualSize) &&
       (psect->SizeOfRawData - psect->Misc.VirtualSize >= 0x20) )
  {
   dwrvadest = psect->VirtualAddress + psect->Misc.VirtualSize;
   break;
  }
 } //for(dwsectnum)

 if (dwsectnum == ppe->FileHeader.NumberOfSections)
 {
  FreeLibrary(hmod);
  SetLastError(-1);
  return FALSE;
 }

 //---------------- search image for 0x74-case switch table
 cbmodsize = ppe->OptionalHeader.SizeOfImage;

 pdw   = (PDWORD)hmod;
 pvend = pdw + (cbmodsize / 4) - /*0x74 /*IE 5.0 SP4 only has 0x72 cases*/0x72;

 for ( ; pdw != pvend; pdw = (PDWORD)((PBYTE)pdw + 1))
 {
  if (*pdw >= (DWORD)hmod && (*pdw - (DWORD)hmod) < cbmodsize)
  {
   for (dw = 1; dw != /*0x74*/0x72; dw++)
   {
    if (pdw[dw] < (DWORD)hmod || (pdw[dw] - (DWORD)hmod) > cbmodsize)
     break;
   }

   if ( dw == /*0x74*/0x72 &&  // overlapping cases are a "signature" for the switch table
        pdw[0x00] == pdw[0x02] &&
        pdw[0x00] == pdw[0x63] &&
        pdw[0x00] == pdw[0x64] &&
        pdw[0x01] == pdw[0x5A] &&
        pdw[0x17] == pdw[0x1B] &&
        pdw[0x5E] == pdw[0x5F] )
   {
    break;
   }
  }
 } //for(pdw)

 if (pdw == pvend)
 {
  FreeLibrary(hmod);
  SetLastError(-1);
  return FALSE;
 }

 //---------------- search case 0x23 code for VT_EMPTY assignment instruction
 pb = (PBYTE)(pdw[0x23]);

 lofs  = 0;
 dwlen = 0;
 bebp  = FALSE;

 for (dw = 0x40; dw != 0; dw--, pb++)
 {
  if (pb[0x00] != 0x66)    // 66h: operand size prefix ('vt' is a WORD-size field)
   continue;

  if (pb[0x01] == 0xC7)    // C7h/0: MOV mem, imm
  {
   switch (pb[0x02])
   {
   case 0x44:    // ModRM=44h: 8-bit offset, SIB
    if (pb[0x03] != 0x24 || pb[0x05] != 0 || pb[0x06] != 0) // SIB=24h: ESP
     continue;
    lofs  = (LONG)*(char*)(pb + 0x04);
    dwlen = 0x07;
    bebp  = FALSE;
    break;

   case 0x45:    // ModRM=45h: 8-bit offset, EBP
    if (pb[0x04] != 0 || pb[0x05] != 0)
     continue;
    lofs  = (LONG)*(char*)(pb + 0x03);
    dwlen = 0x06;
    bebp  = TRUE;
    break;

   case 0x84:    // ModRM=84h: 32-bit offset, SIB
    if (pb[0x03] != 0x24 || pb[0x08] != 0 || pb[0x09] != 0) // SIB=24h: ESP
     continue;
    lofs  = *(LONG*)(pb + 0x04);
    dwlen = 0x0A;
    bebp  = FALSE;
    break;

   case 0x85:    // ModRM=85h: 32-bit offset, EBP
    if (pb[0x07] != 0 || pb[0x08] != 0)
     continue;
    lofs  = *(LONG*)(pb + 0x03);
    dwlen = 0x09;
    bebp  = TRUE;
    break;

   default:
    continue;
   }
  }
  else if (pb[0x01] == 0x83)   // 83h/4: AND mem, simm8
  {
   switch (pb[0x02])
   {
   case 0x64:    // ModRM=64h: 8-bit offset, SIB
    if (pb[0x03] != 0x24 || pb[0x05] != 0) //SIB=24h: ESP
     continue;
    lofs  = (LONG)*(char*)(pb + 0x04);
    dwlen = 0x06;
    bebp  = FALSE;
    break;

   case 0x65:    // ModRM=65h: 8-bit offset, EBP
    if (pb[0x04] != 0)
     continue;
    lofs  = (LONG)*(char*)(pb + 0x03);
    dwlen = 0x05;
    bebp  = TRUE;
    break;

   case 0xA4:    // ModRM=A4h: 32-bit offset, SIB
    if (pb[0x03] != 0x24 || pb[0x08] != 0) // SIB=24h: ESP
     continue;
    lofs  = *(LONG*)(pb + 0x04);
    dwlen = 0x09;
    bebp  = FALSE;
    break;

   case 0xA5:    // ModRM=A5h: 32-bit offset, EBP
    if (pb[0x07] != 0)
     continue;
    lofs  = *(LONG*)(pb + 0x03);
    dwlen = 0x08;
    bebp  = TRUE;
    break;

   default:
    continue;
   }
  }
  else continue;

  if ((lofs & 3) != 0)    // variable will always be DWORD-aligned on stack
   continue;

  if (bebp)
  {
   if (lofs > -0x04 || lofs < -0x800) // EBP-relative must be negative
    continue;
  }
  else
  {
   if (lofs < 0 || lofs > 0x800)  // ESP-relative must be positive
    continue;
  }

  dwrva = (UINT_PTR)pb - (UINT_PTR)hmod;
  break;
 } //for(dw)

 FreeLibrary(hmod);

 if (dw == 0)
 {
  SetLastError(-1);
  return FALSE;
 }

 //---------------- read original JScript.dll into memory
 hfile = CreateFile(szOriginalDLL, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL);

 if (hfile == INVALID_HANDLE_VALUE)
  return FALSE;

 cbmodsize = GetFileSize(hfile, NULL);

 if (cbmodsize == INVALID_FILE_SIZE)
 {
  dwerr = GetLastError();
  CloseHandle(hfile);
  SetLastError(dwerr);
  return FALSE;
 }

 pb = (PBYTE)LocalAlloc(LMEM_FIXED, cbmodsize);

 if (pb == NULL)
 {
  dwerr = GetLastError();
  CloseHandle(hfile);
  SetLastError(dwerr);
  return FALSE;
 }

 if (!ReadFile(hfile, pb, cbmodsize, &cb, NULL) || cb != cbmodsize)
 {
  dwerr = GetLastError();
  CloseHandle(hfile);
  LocalFree(pb);
  SetLastError(dwerr);
  return FALSE;
 }

 CloseHandle(hfile);

 //---------------- patch in-memory file and write it to patched DLL
 ppe   = (PIMAGE_NT_HEADERS)(pb + ((PIMAGE_DOS_HEADER)pb)->e_lfanew);
 psect = IMAGE_FIRST_SECTION(ppe);
 psect += dwsectnum;

 pbdest = TranslateRVAToRawPtr(pb, dwrvadest);

 psect->Misc.VirtualSize += 0x20;

 pbdest[0x00] = 0x60;     // PUSHAD
 pbdest[0x01] = 0x8D;     // LEA EDI, [{ESP,EBP}+ofs32]
 pbdest[0x02] = 0xBC;
 pbdest[0x03] = (bebp ? 0x25 : 0x24);
 *(LONG*)(pbdest + 0x04) = (bebp ? lofs : lofs + 0x20); // (0x20 to compensate for PUSHAD effect on stack)
 pbdest[0x08] = 0x33;     // XOR EAX, EAX
 pbdest[0x09] = 0xC0;
 *(DWORD*)(pbdest + 0x0A) = 0xABABABAB;   // STOSD / STOSD / STOSD / STOSD
 pbdest[0x0E] = 0x61;     // POPAD
 pbdest[0x0F] = 0xE9;     // JMP rel32
 *(DWORD*)(pbdest + 0x10) = (dwrva + dwlen) - (dwrvadest + 0x14);

 pbdest = TranslateRVAToRawPtr(pb, dwrva);

 pbdest[0x00] = 0xE9;     // JMP rel32
 *(DWORD*)(pbdest + 0x01) = dwrvadest - (dwrva + 5);

 hfile = CreateFile(szPatchDLL, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

 if (hfile == INVALID_HANDLE_VALUE)
 {
  dwerr = GetLastError();
  LocalFree(pb);
  SetLastError(dwerr);
  return FALSE;
 }

 if (!WriteFile(hfile, pb, cbmodsize, &dw, NULL) || dw != cbmodsize)
 {
  dwerr = GetLastError();
  CloseHandle(hfile);
  LocalFree(pb);
  SetLastError(dwerr);
  return FALSE;
 }

 CloseHandle(hfile);

 LocalFree(pb);

 SetLastError(ERROR_SUCCESS);
 return TRUE;
} //CreateJScriptPatchDLL()



// WinMain

int WINAPI WinMain(
 IN HINSTANCE  hInstance,
 IN HINSTANCE  hPrevInstance,
 IN LPSTR  lpCmdLine,
 IN int   nShowCmd)
{
 char   szsystem32[MAX_PATH+8];
 char   szoriginal[MAX_PATH+40];
 char   szpatch[MAX_PATH+40];
 UINT   u;
 DWORD   dwerr;

 //----------------
 if ( lpCmdLine != NULL && ((strstr(lpCmdLine, "/?") != NULL) || (strstr(lpCmdLine, "-?") != NULL)) )
 {
  MessageBox(NULL, ":::/n"
                   ":::  Microsoft Internet Explorer createTextRange patch/n"
                   ":::  eEye Digital Security - www.eeye.com - 03/24/2006/n"
                   ":::/n",
             "eEye Digital Security", MB_OK);
  return -1;
 }

 //---------------- get %SystemRoot%/system32 path
 u = GetSystemDirectory(szsystem32, sizeof(szsystem32) - 1);

 if (u == 0 || u >= sizeof(szsystem32) - 1)
 {
  dwerr = GetLastError();
  return (dwerr == 0 ? ERROR_PATH_NOT_FOUND : (int)dwerr);
 }

 if (szsystem32[u-1] != '//')
 {
  szsystem32[u] = '//';
  szsystem32[u+1] = 0;
 }
 else szsystem32[u] = 0;

 _snprintf(szoriginal, sizeof(szoriginal), "%sjscript.dll", szsystem32);
 szoriginal[sizeof(szoriginal)-1] = 0;

 _snprintf(szpatch,    sizeof(szpatch),    "%sjscript-eeye-patch20.dll", szsystem32);
 szpatch[sizeof(szpatch)-1] = 0;

 //---------------- create patched JScript.dll
 if (!CreateJScriptPatchDLL(szoriginal, szpatch))
 {
  dwerr = GetLastError();
  return (dwerr == 0 ? -1 : (int)dwerr);
 }

 return 0;
} //WinMain()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值