Chinaunix首页 | 论坛 | 博客
  • 博客访问: 368491
  • 博文数量: 715
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 5005
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 14:46
文章分类

全部博文(715)

文章存档

2011年(1)

2008年(714)

我的朋友

分类:

2008-10-13 16:32:35

题目太罗嗦,不知所云!我先解释一下
<一dll导出一个函数Add,用加壳工具对它进行加壳,加壳时让此加壳工具把原来的导出表hide,现一exe想动态调用加过壳的dll中的Add函数,可以吗?>

动态连接函数的方法: LoadLibrary,GetProcAddress,壳在我们LoadLibrary返回时就把原始文件Fix好在内存中了!
                cmpb    [esp + 8], 1//是DLL_PROCESS_ATTACH才Fix
                jnz     reloc_end_jmp
那GetProcAddress可以找到在壳中没导出而在原始文件导出的函数吗?
(Add函数在原始文件中导出了,但加过壳后就被hide了)
代码伺候:(reactos的代码)


GetProcAddress( HMODULE hModule, LPCSTR lpProcName )
{
 ANSI_STRING ProcedureName;
 FARPROC fnExp = NULL;

 if (HIWORD(lpProcName) != 0)
 {
  RtlInitAnsiString (&ProcedureName,
                     (LPSTR)lpProcName);
  LdrGetProcedureAddress ((PVOID)hModule,
                          &ProcedureName,
                          0,
                          (PVOID*)&fnExp);
 }
 else
 {
  LdrGetProcedureAddress ((PVOID)hModule,
                          NULL,
                          (ULONG)lpProcName,
                          (PVOID*)&fnExp);
 }

 return fnExp;
}


NTSTATUS NTAPI
LdrGetProcedureAddress (IN PVOID BaseAddress,
                        IN PANSI_STRING Name,
                        IN ULONG Ordinal,
                        OUT PVOID *ProcedureAddress)
{
   if (Name && Name->Length)
     {
       TRACE_LDR("LdrGetProcedureAddress by NAME - %Z\n", Name);
     }
   else
     {
       TRACE_LDR("LdrGetProcedureAddress by ORDINAL - %d\n", Ordinal);
     }

   DPRINT("LdrGetProcedureAddress (BaseAddress %p Name %Z Ordinal %lu ProcedureAddress %p)\n",
          BaseAddress, Name, Ordinal, ProcedureAddress);

   if (Name && Name->Length)
     {
       /* by name */
       *ProcedureAddress = LdrGetExportByName(BaseAddress, (PUCHAR)Name->Buffer, 0xffff);
       if (*ProcedureAddress != NULL)
         {
           return STATUS_SUCCESS;
         }
       DPRINT("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name);
     }
   else
     {
       /* by ordinal */
       Ordinal &= 0x0000FFFF;
       *ProcedureAddress = LdrGetExportByOrdinal(BaseAddress, (WORD)Ordinal);
       if (*ProcedureAddress)
         {
           return STATUS_SUCCESS;
         }
       DPRINT("LdrGetProcedureAddress: Can't resolve symbol @%lu\n", Ordinal);
     }
   return STATUS_PROCEDURE_NOT_FOUND;
}

 

/**********************************************************************
 * NAME                                                         LOCAL
 *      LdrGetExportByName
 *
 * DESCRIPTION
 *
 * ARGUMENTS
 *
 * RETURN VALUE
 *
 * REVISIONS
 *
 * NOTE
 *  AddressOfNames and AddressOfNameOrdinals are paralell tables,
 *  both with NumberOfNames entries.
 *
 */
static PVOID
LdrGetExportByName(PVOID BaseAddress,
                   PUCHAR SymbolName,
                   WORD Hint)
{
   PIMAGE_EXPORT_DIRECTORY      ExportDir;
   PDWORD                       * ExFunctions;
   PDWORD                       * ExNames;
   USHORT                       * ExOrdinals;
   PVOID                        ExName;
   ULONG                        Ordinal;
   PVOID                        Function;
   LONG minn, maxn;
   ULONG ExportDirSize;

   DPRINT("LdrGetExportByName %p %s %hu\n", BaseAddress, SymbolName, Hint);

   ExportDir = (PIMAGE_EXPORT_DIRECTORY)
     RtlImageDirectoryEntryToData(BaseAddress,
                                  TRUE,
                                  IMAGE_DIRECTORY_ENTRY_EXPORT,
                                  &ExportDirSize);
   if (ExportDir == NULL)
     {
        DPRINT1("LdrGetExportByName(): no export directory!\n");
        return NULL;
     }


   //The symbol names may be missing entirely
   if (ExportDir->AddressOfNames == 0)
   {
      DPRINT("LdrGetExportByName(): symbol names missing entirely\n");
      return NULL;
   }

   /*
    * Get header pointers
    */
   ExNames = (PDWORD *)RVA(BaseAddress,
                           ExportDir->AddressOfNames);
   ExOrdinals = (USHORT *)RVA(BaseAddress,
                              ExportDir->AddressOfNameOrdinals);
   ExFunctions = (PDWORD *)RVA(BaseAddress,
                               ExportDir->AddressOfFunctions);

   /*
    * Check the hint first
    */
   if (Hint < ExportDir->NumberOfNames)
     {
        ExName = RVA(BaseAddress, ExNames[Hint]);
        if (strcmp(ExName, (PCHAR)SymbolName) == 0)
          {
             Ordinal = ExOrdinals[Hint];
             Function = RVA(BaseAddress, ExFunctions[Ordinal]);
             if (((ULONG)Function >= (ULONG)ExportDir) &&
                 ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
               {
                  DPRINT("Forward: %s\n", (PCHAR)Function);
                  Function = LdrFixupForward((PCHAR)Function);
                  if (Function == NULL)
                    {
                      DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
                    }
                  return Function;
               }
             if (Function != NULL)
               return Function;
          }
     }

   /*
    * Binary search
    */
   minn = 0;
   maxn = ExportDir->NumberOfNames - 1;
   while (minn <= maxn)
     {
        LONG mid;
        LONG res;

        mid = (minn + maxn) / 2;

        ExName = RVA(BaseAddress, ExNames[mid]);
        res = strcmp(ExName, (PCHAR)SymbolName);
        if (res == 0)
          {
             Ordinal = ExOrdinals[mid];
             Function = RVA(BaseAddress, ExFunctions[Ordinal]);
             if (((ULONG)Function >= (ULONG)ExportDir) &&
                 ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
               {
                  DPRINT("Forward: %s\n", (PCHAR)Function);
                  Function = LdrFixupForward((PCHAR)Function);
                  if (Function == NULL)
                    {
                      DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
                    }
                  return Function;
               }
             if (Function != NULL)
               return Function;
          }
        else if (minn == maxn)
          {
             DPRINT("LdrGetExportByName(): binary search failed\n");
             break;
          }
        else if (res > 0)
          {
             maxn = mid - 1;
          }
        else
          {
             minn = mid + 1;
          }
     }

   DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
   return (PVOID)NULL;
}

 

 

/**********************************************************************
 * NAME                                                         LOCAL
 *      LdrGetExportByName
 *
 * DESCRIPTION
 *
 * ARGUMENTS
 *
 * RETURN VALUE
 *
 * REVISIONS
 *
 * NOTE
 *  AddressOfNames and AddressOfNameOrdinals are paralell tables,
 *  both with NumberOfNames entries.
 *
 */
static PVOID
LdrGetExportByName(PVOID BaseAddress,
                   PUCHAR SymbolName,
                   WORD Hint)
{
   PIMAGE_EXPORT_DIRECTORY      ExportDir;
   PDWORD                       * ExFunctions;
   PDWORD                       * ExNames;
   USHORT                       * ExOrdinals;
   PVOID                        ExName;
   ULONG                        Ordinal;
   PVOID                        Function;
   LONG minn, maxn;
   ULONG ExportDirSize;

   DPRINT("LdrGetExportByName %p %s %hu\n", BaseAddress, SymbolName, Hint);

   ExportDir = (PIMAGE_EXPORT_DIRECTORY)
     RtlImageDirectoryEntryToData(BaseAddress,
                                  TRUE,
                                  IMAGE_DIRECTORY_ENTRY_EXPORT,
                                  &ExportDirSize);
   if (ExportDir == NULL)
     {
        DPRINT1("LdrGetExportByName(): no export directory!\n");
        return NULL;
     }


   //The symbol names may be missing entirely
   if (ExportDir->AddressOfNames == 0)
   {
      DPRINT("LdrGetExportByName(): symbol names missing entirely\n");
      return NULL;
   }

   /*
    * Get header pointers
    */
   ExNames = (PDWORD *)RVA(BaseAddress,
                           ExportDir->AddressOfNames);
   ExOrdinals = (USHORT *)RVA(BaseAddress,
                              ExportDir->AddressOfNameOrdinals);
   ExFunctions = (PDWORD *)RVA(BaseAddress,
                               ExportDir->AddressOfFunctions);

   /*
    * Check the hint first
    */
   if (Hint < ExportDir->NumberOfNames)
     {
        ExName = RVA(BaseAddress, ExNames[Hint]);
        if (strcmp(ExName, (PCHAR)SymbolName) == 0)
          {
             Ordinal = ExOrdinals[Hint];
             Function = RVA(BaseAddress, ExFunctions[Ordinal]);
             if (((ULONG)Function >= (ULONG)ExportDir) &&
                 ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
               {
                  DPRINT("Forward: %s\n", (PCHAR)Function);
                  Function = LdrFixupForward((PCHAR)Function);
                  if (Function == NULL)
                    {
                      DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
                    }
                  return Function;
               }
             if (Function != NULL)
               return Function;
          }
     }

   /*
    * Binary search
    */
   minn = 0;
   maxn = ExportDir->NumberOfNames - 1;
   while (minn <= maxn)
     {
        LONG mid;
        LONG res;

        mid = (minn + maxn) / 2;

        ExName = RVA(BaseAddress, ExNames[mid]);
        res = strcmp(ExName, (PCHAR)SymbolName);
        if (res == 0)
          {
             Ordinal = ExOrdinals[mid];
             Function = RVA(BaseAddress, ExFunctions[Ordinal]);
             if (((ULONG)Function >= (ULONG)ExportDir) &&
                 ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
               {
                  DPRINT("Forward: %s\n", (PCHAR)Function);
                  Function = LdrFixupForward((PCHAR)Function);
                  if (Function == NULL)
                    {
                      DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
                    }
                  return Function;
               }
             if (Function != NULL)
               return Function;
          }
        else if (minn == maxn)
          {
             DPRINT("LdrGetExportByName(): binary search failed\n");
             break;
          }
        else if (res > 0)
          {
             maxn = mid - 1;
          }
        else
          {
             minn = mid + 1;
          }
     }

   DPRINT1("LdrGetExportByName(): failed to find %s\n",SymbolName);
   return (PVOID)NULL;
}

通过代码可以得出:可以正常调用!

ps:以前发现过有壳可以hide导出表的,但刚才没找到这样的壳了,等会继续找,证明这个结论!

posted on 2007-04-27 12:57 垃圾一堆 阅读(1443)   

--------------------next---------------------

阅读(222) | 评论(0) | 转发(0) |
0

上一篇:Ring0Prolog

下一篇:Zw*与Nt*的区别

给主人留下些什么吧!~~