现在的位置: 首页 > 综合 > 正文

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

2013年10月07日 ⁄ 综合 ⁄ 共 23244字 ⁄ 字号 评论关闭
语言核心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
) != NULL)
  {
    ThisLibrary = LoadLibrary(DefaultSystemAPI
);
    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
;
  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计划,详情请登陆http://monkeycz.blogbus.com

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

抱歉!评论已关闭.