邪恶八进制信息安全团队技术讨论组's Archiver

sunwear 2005-11-19 15:21

[转载]易语言核心runtime的loader和部分services的逆向工程

信息来源:看雪学院技术论坛
文章作者:monkeycz
----------
易语言核心runtime的loader和部分services的逆向工程

下面的代码易语言核心runtime(核心支持库krnln.fne)的易格式loader和部分核心services的逆向工程分析。仅仅是逆向分析而已,代码没有经过任何优化。其他就没什么好说的了,具体就看代码吧。

注:和E-Code Explorer配合使用会有意想不到的效果:)


////////////////////////////////////////////////////////////
////   MicroLoader v0.01
////   filename:   MicroLoader.cpp
////   coder:   monkeycz
////   create time:  2005/09/29 23:21
////   fix time:   2005/10/21
////////////////////////////////////////////////////////////


#include "MicroLoader.h"

PIMAGE_DOS_HEADER DosHeader = NULL;
PIMAGE_NT_HEADERS NtHeader = NULL;
PIMAGE_SECTION_HEADER SectionHeader = NULL;
PAPP_HEADER_INFO ECodeHeaderInfo = NULL;
PSECTION_INFO ThisSectionInfo = NULL;
PRELOCATION_INF ThisRelocationInfo = NULL;
UINT32 NumberOfSections = 0;
UINT32 ESectionVA = 0;
char SectionName[IMAGE_SIZEOF_SHORT_NAME + 1];
UINT32 ServerPointTable[ESERVERCOUNT];

typedef void (__stdcall* ECODESTART)(void);
ECODESTART ECodeStart = NULL;

PFN_GET_LIB_INFO GetThisNewInfo = NULL;

PSECTION_INFO pConstSectionOffset = NULL;
PSECTION_INFO pWinFormSectionOffset = NULL;
PSECTION_INFO pHelpFuncSectionOffset = NULL;
PSECTION_INFO pCodeSectionOffset = NULL;
PSECTION_INFO pVarSectionOffset = NULL;

PDLLCMD DllCmdHead = NULL;
PDLLCMD ThisDllCmd = NULL;
UINT32 DllCmdNO = 0;

PLIBINFO LibInfoHead = NULL;
PLIBINFO ThisLibInfo = NULL;
LIBSTRINGINFO ThisLibStringInfo;
UINT32 LibCount = 0;

UINT32 SaveAAddress = 0;

typedef void (__stdcall* UNKNOWFUN)(void);
UNKNOWFUN UnKnowFun = NULL;
HMODULE ThisLibrary = NULL;

HANDLE ThisHeap = NULL;

char* LibStringHead = NULL;
char* ThisLibString = NULL;

char ThisLibFileName[256];

PFN_EXECUTE_CMD** ThisCmdsFuncHead = NULL;
UINT32 LibCmdNO = 0;

PFN_NOTIFY_SYS MyNotifySys = NULL;
PFN_NOTIFY_LIB ThisNotifyLib = NULL;

char* ThisCmdLine = NULL;

char FileName_Full[256];
char FileName_Name[256];
char FileName_Path[256];

typedef void (__stdcall* GETNEWSOCK)(UINT32 Param1);
GETNEWSOCK GetNewSock = NULL;

char ErrorString[256];

INT ThisBaseCmdOffset = -1;
PFN_EXECUTE_CMD* ThisExecuteCmdPoint = NULL;

//定义临时变量
UINT32 i = 0;
UINT32 temp = 0;
UINT32* ptemp = NULL;
bool FindOK = false;

//声明函数
void Exit(void);
void _cdecl ServerFunction_09(UINT32 Param1);
UINT32 _cdecl ServerFunction_06(UINT32 Param1);

//实现核心基本命令
void _cdecl bnot (PMDATA_INF pRetData, INT nArgCount, PMDATA_INF pArgInf)
{
  pRetData->m_int = ~(pArgInf->m_int);
  pRetData->m_dtDataType = SDT_INT;
  return;
}

void _cdecl band (PMDATA_INF pRetData, INT nArgCount, PMDATA_INF pArgInf)
{
  INT result = 0;
  result = pArgInf->m_int;
  for(int i = 1; i <= (nArgCount - 1); i++)
  {
   result = result & (pArgInf + i)->m_int;
  }
  pRetData->m_int = result;
  pRetData->m_dtDataType = SDT_INT;
  return;
}

void _cdecl bor (PMDATA_INF pRetData, INT nArgCount, PMDATA_INF pArgInf)
{
  INT result = 0;
  result = pArgInf->m_int;
  for(int i = 1; i <= (nArgCount - 1); i++)
  {
   result = result | (pArgInf + i)->m_int;
  }
  pRetData->m_int = result;
  pRetData->m_dtDataType = SDT_INT;
  return;
}

void _cdecl bxor (PMDATA_INF pRetData, INT nArgCount, PMDATA_INF pArgInf)
{
  INT result = 0;
  result = pArgInf->m_int;
  for(int i = 1; i <= (nArgCount - 1); i++)
  {
   result = result ^ (pArgInf + i)->m_int;
  }
  pRetData->m_int = result;
  pRetData->m_dtDataType = SDT_INT;
  return;
}

void _cdecl shl (PMDATA_INF pRetData, INT nArgCount, PMDATA_INF pArgInf)
{
  pRetData->m_int = pArgInf->m_int << (pArgInf + 1)->m_int;
  pRetData->m_dtDataType = SDT_INT;
  return;
}

void _cdecl shr (PMDATA_INF pRetData, INT nArgCount, PMDATA_INF pArgInf)
{
  pRetData->m_int = pArgInf->m_int >> (pArgInf + 1)->m_int;
  pRetData->m_dtDataType = SDT_INT;
  return;
}

void _cdecl pstr (PMDATA_INF pRetData, INT nArgCount, PMDATA_INF pArgInf)
{
  char* ThisStr = NULL, *NewStr = NULL;
  UINT32 ThisStrLen = 0;
  
  ThisStr = (char*)pArgInf->m_int;

  try
  {
   ThisStrLen = strlen(ThisStr);
  }
  catch(...)
  {
   MessageBoxA(0, ERROR_021, "error", MB_ICONERROR);
   ServerFunction_09(0);
   return;
  }

  if(ThisStrLen != 0)
  {
   NewStr = (char *)ServerFunction_06(ThisStrLen + 1);

   memcpy(NewStr, ThisStr, ThisStrLen + 1);
  }
  else
  {
   NewStr = NULL;
  }
   
  pRetData->m_pText = NewStr;
  pRetData->m_dtDataType = SDT_TEXT;
  return;
}

void _cdecl pbin (PMDATA_INF pRetData, INT nArgCount, PMDATA_INF pArgInf)
{
  unsigned char* ThisBin = NULL, *NewBin = NULL;
  UINT32 ThisBinLen = 0, *NewBinHead = NULL;

  ThisBin = (unsigned char*)pArgInf->m_int;
  ThisBinLen = (UINT32)(pArgInf++)->m_int;

  if(ThisBinLen != 0)
  {
   NewBin = (unsigned char *)ServerFunction_06(ThisBinLen + 8);
   NewBinHead = (UINT32*)NewBin;

   memcpy(NewBin + 8, ThisBin, ThisBinLen);
   
   (*NewBinHead) = 0x0001;
   (*(NewBinHead++)) = ThisBinLen;
  }
  else
  {
   NewBin = NULL;
  }

  pRetData->m_pBin = NewBin;
  pRetData->m_dtDataType = SDT_BIN;  
  return;
}


//核心代码从这里开始:)

void Exit(void)
{
  if(DllCmdHead != NULL)
  {
   free(DllCmdHead);
  }
  
  if(LibInfoHead != NULL)
  {
   ThisLibInfo = LibInfoHead;
   for(UINT32 i = 1; i <= LibCount; i++)
   {
    if(ThisLibInfo->ThisLibHandle == NULL || ThisLibInfo->ThisLibInfo == NULL)
    {
      continue;
    }
   
    ThisNotifyLib = ThisLibInfo->ThisLibInfo->m_pfnNotify;
    if(ThisNotifyLib != NULL)
    {
      ThisNotifyLib(NL_FREE_LIB_DATA, 0, 0);
    }
   
    FreeLibrary(ThisLibInfo->ThisLibHandle);
    ThisLibInfo->ThisLibHandle = NULL;
    ThisLibInfo->ThisLibInfo = NULL;

    ThisLibInfo++;
   }
   
   free(LibInfoHead);
  }
  
  if(ThisHeap != NULL)
  {
   HeapDestroy(ThisHeap);
  }

}

__declspec(naked) void _cdecl ServerFunction_09(UINT32 Param1)
{
  __asm
  {
   push ebp
   mov ebp, esp
  }

  if(SaveAAddress != NULL)
  {
   UnKnowFun = (UNKNOWFUN)SaveAAddress;
   UnKnowFun();
  }

  Exit();
  
  ExitProcess(Param1);  
  
  __asm
  {
   ret
  }
}

INT WINAPI ThisNotifySys(INT nMsg, DWORD dwParam1 = 0, DWORD dwParam2 = 0)
{
  PMDATA_INF ThisDataInfo = NULL;
  void* temppoint= NULL;
  DWORD temp = 0;

  switch(nMsg)
  {
   case NAS_GET_APP_ICON:
    //通知系统创建并返回程序的图标
    //和窗口组建相关,不处理
    sprintf(ErrorString, "%s\n\nIntra error number is %d.", ERROR_016, NAS_GET_APP_ICON);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
    ServerFunction_09(0);   
    break;
   case NAS_GET_LIB_DATA_TYPE_INFO:
    //返回指定库定义数据类型的PLIB_DATA_TYPE_INFO定义信息指针
    temp = dwParam1;
    if((temp >> 30) == 0)
    {
      ThisLibInfo = LibInfoHead;
      ThisLibInfo += ((temp >> 16) - 1);
      return (INT)(ThisLibInfo->ThisLibInfo->m_pDataType + (((temp << 16) >> 16) - 1));
    }
    break;
   case NAS_GET_HBITMAP:
    //返回非NULL的HBITMAP句柄(注意使用完毕后释放),否则返回NULL
    //和窗口组建相关,不处理
    sprintf(ErrorString, "%s\n\nIntra error number is %d.", ERROR_016, NAS_GET_HBITMAP);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
    ServerFunction_09(0);   
    break;
   case NAS_GET_LANG_ID:
    //返回当前系统或运行环境所支持的语言ID
    return 1;
   case NAS_GET_VER:
    //返回当前系统或运行环境的版本号
    return 0x00000004;
   case NAS_GET_PATH:
    //返回当前开发或运行环境的某一类目录或文件名,目录名以“\”结束
    switch(dwParam1)
    {
      case 1:
       strcpy((char*)dwParam2, FileName_Path);
       return (INT)FileName_Path;
       break;
      case 2001:
       strcpy((char*)dwParam2, FileName_Path);
       return (INT)FileName_Path;
       break;
      case 2002:
       strcpy((char*)dwParam2, FileName_Name);
       return (INT)FileName_Name;
       break;
      default:
       return NULL;   
    }
   case NRS_UNIT_DESTROIED:
    //通知系统指定的单元已经被销毁。
    //和窗口组建相关,不处理。
    sprintf(ErrorString, "%s\n\nIntra error number is %d.", ERROR_016, NRS_UNIT_DESTROIED);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
    ServerFunction_09(0);
    break;
   case NRS_CONVERT_NUM_TO_INT:
    //转换其它数值格式到整数
    ThisDataInfo = (PMDATA_INF)dwParam1;
    switch(ThisDataInfo->m_dtDataType)
    {
      case SDT_SHORT:
       return (int)(ThisDataInfo->m_short);
      case SDT_INT:
       return (int)(ThisDataInfo->m_int);
      case SDT_INT64:
       return (int)(ThisDataInfo->m_int64);
      case SDT_FLOAT:
       return (int)(ThisDataInfo->m_float);
      case SDT_DOUBLE:
       return (int)(ThisDataInfo->m_double);
      default:
       return 0;
    }
    break;
   case NRS_GET_CMD_LINE_STR:
    //取当前命令行文本
    return (INT)ThisCmdLine;
   case NRS_GET_EXE_PATH_STR:
    //取当前执行文件所处目录名称
    return (INT)FileName_Path;
   case NRS_GET_EXE_NAME:
    //取当前执行文件名称
    return (INT)FileName_Name;
   case NRS_GET_UNIT_PTR:
    //取单元对象指针
    //和窗口组建相关,不处理
    sprintf(ErrorString, "%s\n\nIntra error number is %d.", ERROR_016, NRS_GET_UNIT_PTR);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
    ServerFunction_09(0);
    break;
   case NRS_GET_AND_CHECK_UNIT_PTR:
    //取单元对象指针
    //和窗口组建相关,不处理
    sprintf(ErrorString, "%s\n\nIntra error number is %d.", ERROR_016, NRS_GET_AND_CHECK_UNIT_PTR);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
    ServerFunction_09(0);
    break;
   case NRS_EVENT_NOTIFY:
    //通知系统产生了事件
    //和窗口组建相关,不处理
    sprintf(ErrorString, "%s\n\nIntra error number is %d.", ERROR_016, NRS_EVENT_NOTIFY);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
    ServerFunction_09(0);
    break;
   /*
   在新版本的支持库中不支持
   case NRS_STOP_PROCESS_EVENT_NOTIFY:
    //通知系统暂停处理事件通知
    //和窗口组建相关,不处理
    sprintf(ErrorString, "%s\n\nIntra error number is %d.", ERROR_016, NRS_STOP_PROCESS_EVENT_NOTIFY);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
    ServerFunction_09(0);
    break;
   case NRS_CONTINUE_PROCESS_EVENT_NOTIFY:
    //通知系统继续处理事件通知
    //和窗口组建相关,不处理
    sprintf(ErrorString, "%s\n\nIntra error number is %d.", ERROR_016, NRS_CONTINUE_PROCESS_EVENT_NOTIFY);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
    ServerFunction_09(0);
    break;
   */
   case NRS_DO_EVENTS:
    //通知Windows系统处理所有已有事件
    //我不觉得这种处理方式很好,确定的说,是一种很差的处理方式
    Sleep(1);
    break;
   case NRS_GET_UNIT_DATA_TYPE:
    //成功返回有效的 DATA_TYPE
    //和窗口组建相关,不处理
    sprintf(ErrorString, "%s\n\nIntra error number is %d.", ERROR_016, NRS_GET_UNIT_DATA_TYPE);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
    ServerFunction_09(0);
    break;  
   case NRS_FREE_ARY:
    //释放指定数组数据
    //不会处理T_T,:(
    MessageBoxA(0, ERROR_020, "error", MB_ICONERROR);
    ServerFunction_09(0);
    break;
   case NRS_MALLOC:
    //分配指定空间的内存,所有与易程序交互的内存都必须使用本通知分配
    temppoint = HeapAlloc(ThisHeap, 0, dwParam1);
    if(temppoint == NULL)
    {
      if(dwParam2 == 0)
      {
       MessageBoxA(0, ERROR_017, "error", MB_ICONERROR);
       ServerFunction_09(0);
       return 0;
      }
      else
      {
       return 0;
      }
    }
    return (INT)temppoint;
   case NRS_MFREE:
    //释放已分配的指定内存
    if(dwParam1 != NULL)
    {
      HeapFree(ThisHeap, 0, (void *)dwParam1);
    }
    break;
   case NRS_MREALLOC:
    //重新分配内存
    temppoint = HeapReAlloc(ThisHeap, 0, (void *)dwParam1, dwParam2);
    if(temppoint == NULL)
    {
      MessageBoxA(0, ERROR_018, "error", MB_ICONERROR);
      ServerFunction_09(0);
      return 0;
    }
    return (INT)temppoint;
   case NRS_RUNTIME_ERR:
    //通知系统已经产生运行时错误
    sprintf(ErrorString, "%s\n\nError String is %s", ERROR_019, (char*)dwParam1);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
    ServerFunction_09(0);
    break;
   case NRS_EXIT_PROGRAM:
    //通知系统退出用户程序
    ServerFunction_09(dwParam1);
    break;
   case NRS_EVENT_NOTIFY2:
    //以第二类方式通知系统产生了事件
    //和窗口组建相关,不处理
    sprintf(ErrorString, "%s\n\nIntra error number is %d.", ERROR_016, NRS_EVENT_NOTIFY2);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
    ServerFunction_09(0);
    break;
   case NRS_GET_WINFORM_COUNT:
    //返回当前程序的窗体数目
    //和窗口组建相关,不处理
    sprintf(ErrorString, "%s\n\nIntra error number is %d.", ERROR_016, NRS_GET_WINFORM_COUNT);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
    ServerFunction_09(0);
    break;
   case NRS_GET_WINFORM_HWND:
    //返回指定窗体的窗口句柄,如果该窗体尚未被载入,返回NULL
    //和窗口组建相关,不处理
    sprintf(ErrorString, "%s\n\nIntra error number is %d.", ERROR_016, NRS_GET_WINFORM_HWND);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
    ServerFunction_09(0);
    break;
   case NRS_GET_BITMAP_DATA:
    //返回指定HBITMAP的图片数据,成功返回包含BMP图片数据的HGLOBAL句柄,失败返回NULL
    //和窗口组建相关,不处理
    sprintf(ErrorString, "%s\n\nIntra error number is %d.", ERROR_016, NRS_GET_BITMAP_DATA);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
    ServerFunction_09(0);
    break;
   case NRS_FREE_COMOBJECT:
    //通知系统释放指定的DTP_COM_OBJECT类型COM对象
    //不支持COM对象,不处理
    sprintf(ErrorString, "%s\n\nIntra error number is %d.", ERROR_016, NRS_FREE_COMOBJECT);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
    ServerFunction_09(0);
    break;  
   case NRS_CHK_TAB_VISIBLE:
    //当选择夹子夹被切换后, 使用本消息通知易系统
    //和窗口组建相关,不处理
    sprintf(ErrorString, "%s\n\nIntra error number is %d.", ERROR_016, NRS_CHK_TAB_VISIBLE);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
    ServerFunction_09(0);
    break;   
   case NRS_GET_PRG_TYPE:
    //返回当前用户程序的类型,为PT_DEBUG_RUN_VER(调试版)或PT_RELEASE_RUN_VER(发布版)
    return PT_RELEASE_RUN_VER;
   default:
    //如果发生例外,不处理
    break;
  }
  
  return 0;
}

bool Init(void)
{
  ThisHeap = HeapCreate(0, 0x1000, 0);
  if(ThisHeap == NULL)
  {
   return false;
  }

  MyNotifySys = ThisNotifySys;

  return true;
}

void _cdecl ServerFunction_00(UINT32 Param1)
{
  
  sprintf(ErrorString, "%s\n\nIntra error number is %d.", ERROR_006, Param1);
  MessageBoxA(0, ErrorString, "error", MB_ICONERROR);
  
  ServerFunction_09(0);
  
  return;
}

__declspec(naked) void _stdcall ServerFunction_01(void)
{

  __asm
  {
   pop temp
   push eax
   pop DllCmdNO
  }

  ThisDllCmd = DllCmdHead;
  ThisDllCmd += DllCmdNO;

  if((* ThisDllCmd->DllFileName) == NULL)
  {
   i = 0;
   while((* DefaultSystemAPI[i]) != NULL)
   {
    ThisLibrary = LoadLibrary(DefaultSystemAPI[i]);
    UnKnowFun = (UNKNOWFUN)GetProcAddress(ThisLibrary, ThisDllCmd->DllCmdName);
    if(UnKnowFun != NULL)
    {
      __asm
      {
       //call UnKnowFun
       //这个地方可能会引起杀毒软件的误报,如果有必要的话,需要处理一下
       push temp
       jmp UnKnowFun
      }
      break;
    }
    else
    {
      FreeLibrary(ThisLibrary);
      i++;
    }

   }

   if(UnKnowFun == NULL)
   {
    ServerFunction_00(0);
   }
   
  }
  else
  {
   ThisLibrary = LoadLibrary(ThisDllCmd->DllFileName);
   UnKnowFun = (UNKNOWFUN)GetProcAddress(ThisLibrary, ThisDllCmd->DllCmdName);
   if(UnKnowFun != NULL)
   {
    __asm
    {
      //call UnKnowFun
      push temp
      jmp UnKnowFun
    }
   }
   else
   {
    ServerFunction_00(0);
   }   
  }
  
  __asm
  {
   push eax
  }
  
  FreeLibrary(ThisLibrary);
  
  __asm
  {
   pop eax
   push temp
   ret
  }
  
}

__declspec(naked) void _cdecl ServerFunction_02(void)
{
  
  __asm
  {
   push ebp
   mov ebp,esp
   mov LibCmdNO,eax
  }
  ThisLibInfo = LibInfoHead;
  ThisLibInfo += LibCmdNO;
  if(ThisLibInfo->ThisLibHandle == NULL || ThisLibInfo->ThisLibInfo == NULL)
  {
   sprintf(ErrorString, "%s\n\nIntra error string is \"%s\".", ERROR_014, ThisLibInfo->ThisLibName);
   MessageBoxA(0, ErrorString, "error", MB_ICONERROR);  
   ServerFunction_09(0);  
  }
  ThisCmdsFuncHead = &(ThisLibInfo->ThisLibInfo->m_pCmdsFunc);
  __asm
  {
   mov edx,[ThisCmdsFuncHead]
   add ebx,[edx]
   lea edx,dword ptr ss:[esp+0x0c]
   sub esp,0x0c
   push edx
   push dword ptr ss:[esp+0x18]
   mov dword ptr ss:[esp+0x08],0
   mov dword ptr ss:[esp+0x0c],0
   mov dword ptr ss:[esp+0x10],0
   lea edx,dword ptr ss:[esp+0x08]
   push edx
   call dword ptr ds:[ebx]
   mov eax,dword ptr ss:[esp+0x0c]
   mov edx,dword ptr ss:[esp+0x10]
   mov ecx,dword ptr ss:[esp+0x14]
   mov esp,ebp
   pop ebp
   retn
  }
}

__declspec(naked) void _cdecl ServerFunction_03(void)
{
  
  __asm
  {
   push ebp
   mov ebp,esp
   mov LibCmdNO,0
   mov ThisBaseCmdOffset,ebx
  }
  temp = 0;
  FindOK = false;
  while(KernelBaseCmd[temp].CmdOffset != -1)
  {
   if(KernelBaseCmd[temp].CmdOffset == ThisBaseCmdOffset)
   {
    FindOK = true;
    ThisExecuteCmdPoint = &(KernelBaseCmd[temp].CmdPoint);
    break;
   }
   temp++;
  }
  if(FindOK == false)
  {
   ThisLibInfo = LibInfoHead;
   ThisLibInfo += LibCmdNO;
   if(ThisLibInfo->ThisLibHandle == NULL || ThisLibInfo->ThisLibInfo == NULL)
   {
    sprintf(ErrorString, "%s\n\nIntra error string is \"%s\".", ERROR_015, ThisLibInfo->ThisLibName);
    MessageBoxA(0, ErrorString, "error", MB_ICONERROR);   
    ServerFunction_09(0);  
   }
   ThisCmdsFuncHead = &(ThisLibInfo->ThisLibInfo->m_pCmdsFunc);

   __asm
   {
    mov eax,[ThisCmdsFuncHead]
    add ebx,dword ptr ds:[eax]
   }
  }
  else
  {
   __asm
   {
    mov ebx,ThisExecuteCmdPoint
   }
  }
  __asm
  {
   lea eax,dword ptr ss:[esp+0x0c]
   sub esp,0x0c
   push eax
   push dword ptr ss:[esp+0x18]
   xor eax,eax
   mov dword ptr ss:[esp+0x08],eax
   mov dword ptr ss:[esp+0x0c],eax
   mov dword ptr ss:[esp+0x10],eax
   lea edx,dword ptr ss:[esp+0x08]
   push edx
   call dword ptr ds:[ebx]
   mov eax,dword ptr ss:[esp+0x0C]
   mov edx,dword ptr ss:[esp+0x10]
   mov ecx,dword ptr ss:[esp+0x14]
   mov esp,ebp
   pop ebp
   retn  
  }

}

void _cdecl ServerFunction_04(void)
{
  MessageBoxA(0, ERROR_012, "error", MB_ICONERROR);
  ServerFunction_09(0);
  return;
}

void _cdecl ServerFunction_05(void)
{
  MessageBoxA(0, ERROR_013, "error", MB_ICONERROR);
  ServerFunction_09(0);
  return;
}

__declspec(naked) UINT32 _cdecl ServerFunction_06(UINT32 Param1)
{
  __asm
  {
   push ebp
   mov ebp,esp
   push ecx
   mov eax,Param1
   mov ecx,ThisHeap
  }
  HeapAlloc(ThisHeap, 0, Param1);
  __asm
  {
   mov dword ptr ss:[ebp-0x04],eax
   cmp dword ptr ss:[ebp-0x04],0
   jnz okey
  }
  MessageBoxA(0, ERROR_008, "error", MB_ICONERROR);
  ServerFunction_09(0);
  __asm
  {
okey:
   mov eax,dword ptr ss:[ebp-0x04]
   mov esp,ebp
   pop ebp
   retn
  }
}

__declspec(naked) UINT32 _cdecl ServerFunction_07(UINT32 Param1, UINT32 Param2)
{
  __asm
  {
   push ebp
   mov ebp,esp
   sub esp,0x0c
   cmp Param1,0
   jnz a
   mov eax,Param2
   push eax
   call ServerFunction_06
   add esp,0x04
   jmp end   
a:   
  }
  HeapReAlloc(ThisHeap, 0, (void *)Param1, Param2);
  __asm
  {
   mov Param1,eax
   cmp Param1,0
   jnz b
  }
  MessageBoxA(0, ERROR_010, "error", MB_ICONERROR);
  ServerFunction_09(0);
  __asm
  {
   
b:
   mov eax,Param1
end:
   mov esp,ebp
   pop ebp
   retn
  }
}

void _cdecl ServerFunction_08(UINT32 Param1)
{
  if(Param1 != 0)
  {
   HeapFree(ThisHeap, 0, (void *)Param1);  
  }

  return;
}

void _cdecl ServerFunction_10(UINT32 Param1)
{  
  return;
}

void _cdecl ServerFunction_11(UINT32 Param1)
{
  MessageBoxA(0, ERROR_011, "error", MB_ICONERROR);
  ServerFunction_09(0);
  return;
}

void _cdecl ServerFunction_12(UINT32 Param1)
{
  SaveAAddress = Param1;
  return;
}

void InitServerPointTable(void)
{
  ServerPointTable[0] = (UINT32)ServerFunction_00;
  ServerPointTable[1] = (UINT32)ServerFunction_01;
  ServerPointTable[2] = (UINT32)ServerFunction_02;
  ServerPointTable[3] = (UINT32)ServerFunction_03;
  ServerPointTable[4] = (UINT32)ServerFunction_04;
  ServerPointTable[5] = (UINT32)ServerFunction_05;
  ServerPointTable[6] = (UINT32)ServerFunction_06;
  ServerPointTable[7] = (UINT32)ServerFunction_07;
  ServerPointTable[8] = (UINT32)ServerFunction_08;
  ServerPointTable[9] = (UINT32)ServerFunction_09;
  ServerPointTable[10] = (UINT32)ServerFunction_10;
  ServerPointTable[11] = (UINT32)ServerFunction_11;
  ServerPointTable[12] = (UINT32)ServerFunction_12;
}

void UpdataServerPointTable(void)
{
  ptemp = (UINT32 *)((UINT32)ECodeHeaderInfo + pHelpFuncSectionOffset->m_nRecordOffset);
  for(i = 0; i <= ESERVERCOUNT - 1; i++)
  {
   (* ptemp) = ServerPointTable[i];
   ptemp++;
  }
}

int APIENTRY WinMain(HINSTANCE hInstance,
              HINSTANCE hPrevInstance,
              LPSTR    lpCmdLine,
              int     nCmdShow)
{
  
  //初始化内部堆栈
  if(Init() == false)
  {
   MessageBoxA(0, ERROR_009, "error", MB_ICONERROR);
   return 0;
  }

  //得到当前命令行
  ThisCmdLine = lpCmdLine;
  
  //获取当前运行环境
  GetModuleFileName(NULL, FileName_Full, 256);
  strcpy(FileName_Name, PathFindFileName(FileName_Full));
  temp = strlen(FileName_Full) - strlen(FileName_Name);
  memcpy(FileName_Path, FileName_Full, temp);
  FileName_Path[temp] = 0;

  
  //获取当前进程基址,遍历SectionTable查找易格式原体
  DosHeader = (PIMAGE_DOS_HEADER)GetModuleHandle(NULL);
  
  if(DosHeader == NULL)
  {
   MessageBoxA(0, ERROR_001, "error", MB_ICONERROR);
   return 0;
  }

  NtHeader = (PIMAGE_NT_HEADERS)((UINT32)DosHeader + DosHeader->e_lfanew);
  NumberOfSections = NtHeader->FileHeader.NumberOfSections;
  
  SectionHeader = (PIMAGE_SECTION_HEADER)((UINT32)NtHeader + sizeof(IMAGE_NT_HEADERS));

  FindOK = false;
  for(i = 1; i <= NumberOfSections; i++)
  {
   
   memcpy(SectionName, SectionHeader->Name, IMAGE_SIZEOF_SHORT_NAME);
   SectionName[IMAGE_SIZEOF_SHORT_NAME + 1] = 0;

   //寻找易格式所在节的方法是:简单的比较当前SectionName是否是“.ecode”
   if(strcmp(SectionName, ESECTIONNAME) == 0)
   {
    //找到了易格式所在的节
    FindOK = true;
    break;
   }

   SectionHeader++;

  }
  
  if(FindOK == false)
  {
   MessageBoxA(0, ERROR_002, "error", MB_ICONERROR);
   return 0;
  }
  
  //定位易格式原体,取易格式原体所在节的基址
  ESectionVA = (UINT32)DosHeader + (UINT32)SectionHeader->VirtualAddress;
  ECodeHeaderInfo = (PAPP_HEADER_INFO)ESectionVA;

  if(ECodeHeaderInfo == NULL)
  {
   MessageBoxA(0, ERROR_003, "error", MB_ICONERROR);
   return 0;
  }

  if(ECodeHeaderInfo->m_dwMark != NEW_E_APP_MARK)
  {
   MessageBoxA(0, ERROR_004, "error", MB_ICONERROR);
   return 0;
  }

  //获取易格式初始化必需的的数据

  //获取各个重要数据段的RVA
  pConstSectionOffset = (PSECTION_INFO)((UINT32)ECodeHeaderInfo + ECodeHeaderInfo->m_nConstSectionOffset);
  pWinFormSectionOffset = (PSECTION_INFO)((UINT32)ECodeHeaderInfo + ECodeHeaderInfo->m_nWinFormSectionOffset);
  pHelpFuncSectionOffset = (PSECTION_INFO)((UINT32)ECodeHeaderInfo + ECodeHeaderInfo->m_nHelpFuncSectionOffset);
  pCodeSectionOffset = (PSECTION_INFO)((UINT32)ECodeHeaderInfo + ECodeHeaderInfo->m_nCodeSectionOffset);
  pVarSectionOffset = (PSECTION_INFO)((UINT32)ECodeHeaderInfo + ECodeHeaderInfo->m_nVarSectionOffset);
  
  //获取DLL命令信息数组
  if(ECodeHeaderInfo->m_nDllCmdCount > 0)
  {
   DllCmdHead = (PDLLCMD)malloc(sizeof(DLLCMD) * ECodeHeaderInfo->m_nDllCmdCount);
   if(DllCmdHead == NULL)
   {
    MessageBoxA(0, ERROR_007, "error", MB_ICONERROR);
    return 0;
   }

   ThisDllCmd = DllCmdHead;

   for(i = 1; i <= (UINT32)ECodeHeaderInfo->m_nDllCmdCount; i++)
   {
    ThisDllCmd->DllFileName = (char *)((UINT32)ECodeHeaderInfo + pConstSectionOffset->m_nRecordOffset + (*(UINT *)((UINT32)ECodeHeaderInfo + sizeof(APP_HEADER_INFO) + (i - 1) * sizeof(INT))));
    ThisDllCmd->DllCmdName = (char *)((UINT32)ECodeHeaderInfo + pConstSectionOffset->m_nRecordOffset + (*(UINT *)((UINT32)ECodeHeaderInfo + sizeof(APP_HEADER_INFO) + (i + ECodeHeaderInfo->m_nDllCmdCount - 1) * sizeof(INT))));
   
    ThisDllCmd++;
   }

  }
  
  //获取需要的支持库并加载
  LibStringHead = (char *)((UINT32)ECodeHeaderInfo + sizeof(APP_HEADER_INFO) + ECodeHeaderInfo->m_nDllCmdCount * sizeof(INT) * 2);

  //统计需要加载的支持库数量
  ThisLibString = LibStringHead;
  LibCount = 0;
  while((* ThisLibString) != NULL)
  {
   LibCount++;
   ThisLibString += (strlen(ThisLibString) + 1);
  }

  //加载支持库
  LibInfoHead = (PLIBINFO)malloc(sizeof(LIBINFO) * LibCount);

  ThisLibInfo = LibInfoHead;

  ThisLibString = LibStringHead;

  while((* ThisLibString) != NULL)
  {
   temp = 0;
   while((* (ThisLibString + temp)) != 0x0d)
   {
    ThisLibStringInfo.LibName[temp] = (* (ThisLibString + temp));
    temp++;
   }
   ThisLibStringInfo.LibName[temp] = 0;

   temp += 1;
   while((* (ThisLibString + temp)) != 0x0d)
   {
    ThisLibStringInfo.ThisGUID[temp - strlen(ThisLibStringInfo.LibName) - 1] = (* (ThisLibString + temp));
    temp++;
   }
   ThisLibStringInfo.ThisGUID[temp] = 0;
   
   ThisLibInfo->ThisLibHandle = NULL;
   ThisLibInfo->ThisLibInfo = NULL;
   strcpy(ThisLibInfo->ThisLibName, ThisLibStringInfo.LibName);
   
   strcpy(ThisLibFileName, ThisLibStringInfo.LibName);
   strcat(ThisLibFileName, ".fne");

   FindOK = false;

   ThisLibInfo->ThisLibHandle = LoadLibrary(ThisLibFileName);
   if(ThisLibInfo->ThisLibHandle == NULL)
   {
    strcpy(ThisLibFileName, ThisLibStringInfo.LibName);
    strcat(ThisLibFileName, ".fnr");

    FindOK = false;
   
    ThisLibInfo->ThisLibHandle = LoadLibrary(ThisLibFileName);

    if(ThisLibInfo->ThisLibHandle == NULL)
    {
      //没有加载成功,继续加载下一个支持库
    }
    else
    {
      FindOK = true;
    }

   }
   else
   {
    FindOK = true;
   }
   
   //加载成功,开始获取支持库信息
   if(FindOK == true)
   {
    GetThisNewInfo = (PFN_GET_LIB_INFO)GetProcAddress(ThisLibInfo->ThisLibHandle, FUNCNAME_GET_LIB_INFO);  
   
    //初始化核心支持库
    GetNewSock = (GETNEWSOCK)GetProcAddress(ThisLibInfo->ThisLibHandle, FUNCNAME_GET_NEW_SOCK);
   
    if(GetNewSock != NULL)
    {
      //这是一段罪恶的代码,江山从此易主。希望新版本的核心支持库能分离初始化函数和加载函数
      GetNewSock(1000);
      __asm
      {
       pop edx
       mov edx,ESectionVA
       push edx  
       call eax   
      }
      Exit();
      return 0;
    }
   
    if(GetThisNewInfo == NULL)
    {
      //载入的库没有输出FUNCNAME_GET_LIB_INFO函数,需要卸载掉
      FreeLibrary(ThisLibInfo->ThisLibHandle);
      ThisLibInfo->ThisLibHandle = NULL;
    }
    else
    {
      ThisLibInfo->ThisLibInfo = GetThisNewInfo();

      if(ThisLibInfo->ThisLibInfo == NULL)
      {
       //输出的PLIB_INFO结构为空,需要卸载这样的支持库
       FreeLibrary(ThisLibInfo->ThisLibHandle);
       ThisLibInfo->ThisLibHandle = NULL;
       ThisLibInfo->ThisLibInfo = NULL;
      }
      else
      {
       if(strcmp(ThisLibInfo->ThisLibInfo->m_szGuid, ThisLibStringInfo.ThisGUID) != 0)
       {
        //加载的支持库和需要的支持库GUID不同,需要卸载支持库
        FreeLibrary(ThisLibInfo->ThisLibHandle);
        ThisLibInfo->ThisLibHandle = NULL;
        ThisLibInfo->ThisLibInfo = NULL;
       }
       else
       {
        //为当前支持库提供Notify函数指针
        ThisNotifyLib = ThisLibInfo->ThisLibInfo->m_pfnNotify;
        if(ThisNotifyLib != NULL)
        {
          ThisNotifyLib(NL_SYS_NOTIFY_FUNCTION, (DWORD)MyNotifySys, 0);
        }

       }

      }   
    }
   }


   ThisLibInfo++;
   
   ThisLibString += (strlen(ThisLibString) + 1);
  }

  
  //获取易格式代码的起始指令地址
  ECodeStart = (ECODESTART)((UINT32)ECodeHeaderInfo + (UINT32)ECodeHeaderInfo->m_nStartCodeOffset);
  
  if(ECodeStart == NULL)
  {
   MessageBoxA(0, ERROR_005, "error", MB_ICONERROR);
   return 0;   
  }
  
  //遍历易格式中所有的数据段,对每个数据段中的重定位信息进行校正
  temp = (UINT32)ECodeHeaderInfo->m_nBeginSectionOffset;
  
  while(temp != 0xFFFFFFFF)
  {
   ThisSectionInfo = (PSECTION_INFO)((UINT32)ECodeHeaderInfo + temp);
   
   if(ThisSectionInfo->m_nReLocationItemCount > 0)
   {
    ThisRelocationInfo = (PRELOCATION_INF)((UINT32)ThisSectionInfo + sizeof(SECTION_INFO));
    for(i = 1; i <= (UINT32)ThisSectionInfo->m_nReLocationItemCount; i++)
    {
      
      ptemp = (UINT32 *)((UINT32)ECodeHeaderInfo + ThisSectionInfo->m_nRecordOffset + ThisRelocationInfo->m_dwOffset);
      
      switch(ThisRelocationInfo->m_btType)
      {
       case RT_HELP_FUNC:  
        (* ptemp) = (* ptemp) + (UINT32)ECodeHeaderInfo + pHelpFuncSectionOffset->m_nRecordOffset;
        break;
       case RT_CONST:
        (* ptemp) = (* ptemp) + (UINT32)ECodeHeaderInfo + pConstSectionOffset->m_nRecordOffset;
        break;
       case RT_GLOBAL_VAR:
        (* ptemp) = (* ptemp) + (UINT32)ECodeHeaderInfo + pVarSectionOffset->m_nRecordOffset;
        break;
       case RT_CODE:
        (* ptemp) = (* ptemp) + (UINT32)ECodeHeaderInfo + pCodeSectionOffset->m_nRecordOffset;
        break;
       default:   
        break;
      }

      ThisRelocationInfo++;  
    }
   }
   temp = (UINT32)ThisSectionInfo->m_nNextSectionOffset;
  }

  //初始化服务指针表
  InitServerPointTable();
  UpdataServerPointTable();

  //至此初始化操作全部完成,转交控制权给易程序
  ECodeStart();

  //清除内部堆栈,准备结束
  Exit();

  return 0;
}


/////////////////////////////////////////////////////////////////////////


上面的代码也是ZanMoon计划(斩月计划)的核心组件MicroLoader的源代码,关于ZanMoon计划,详情请登陆[url]http://monkeycz.blogbus.com[/url]。

关于版权问题:由于涉及到部分头文件的版权问题,我没有发布完整的工程,请大家见谅。这个项目的全部工程,除引用和包含的第三方文档、代码外,全部源代码符合GPL规范。






monkeycz
2005/11/13

页: [1]
© 1999-2008 EvilOctal Security Team