首页
社区
课程
招聘
[原创]易语言核心runtime的loader和部分services的逆向工程
发表于: 2005-11-13 22:35 14734

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

2005-11-13 22:35
14734

易语言核心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计划,详情请登陆http://monkeycz.blogbus.com。

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

monkeycz
2005/11/13


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (27)
雪    币: 3686
活跃值: (1036)
能力值: (RANK:760 )
在线值:
发帖
回帖
粉丝
2
2005-11-13 22:41
0
雪    币: 133
活跃值: (22)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
顶。。。。。
2005-11-13 22:42
0
雪    币: 817
活跃值: (1927)
能力值: ( LV12,RANK:2670 )
在线值:
发帖
回帖
粉丝
4
2005-11-13 23:04
0
雪    币: 270
活跃值: (312)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
5
好文~学习!
2005-11-13 23:11
0
雪    币: 440
活跃值: (827)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
6

非常棒!
2005-11-13 23:36
0
雪    币: 3841
活跃值: (4412)
能力值: (RANK:215 )
在线值:
发帖
回帖
粉丝
7
疯了
2005-11-14 00:28
0
雪    币: 133
活跃值: (22)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
最初由 china 发布
疯了

疯的好 疯了有理,疯了无罪
2005-11-14 00:33
0
雪    币: 298
活跃值: (445)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
9
看不懂
2005-11-14 01:22
0
雪    币: 202
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
2005-11-14 03:13
0
雪    币: 389
活跃值: (912)
能力值: ( LV9,RANK:770 )
在线值:
发帖
回帖
粉丝
11
不懂ing..........
2005-11-14 18:25
0
雪    币: 61
活跃值: (160)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
12
2005-11-14 19:58
0
雪    币: 300
活跃值: (412)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
13
使劲学习,这么多
2005-11-14 20:13
0
雪    币: 671
活跃值: (723)
能力值: ( LV9,RANK:1060 )
在线值:
发帖
回帖
粉丝
14
编程这么强。

可惜偶不会编程,纯支持了。

有时间学学C++啊!
2005-11-14 20:30
0
雪    币: 420
活跃值: (49)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
恐怖,一千年也达不到了
2005-11-14 21:23
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
今天开眼界看了回天书~~~
2005-11-14 23:45
0
雪    币: 116
活跃值: (220)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
17
强帖留名...
其实, 我佩服楼主很久了...
2005-11-15 00:06
0
雪    币: 212
活跃值: (40)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18
看多这个会头痛的。
唉! 天天看,晕得很啊
2005-11-15 08:25
0
雪    币: 3841
活跃值: (4412)
能力值: (RANK:215 )
在线值:
发帖
回帖
粉丝
19
最初由 xIkUg 发布
强帖留名...
其实, 我佩服楼主很久了...


其实我是个导演
2005-11-15 08:26
0
雪    币: 234
活跃值: (370)
能力值: ( LV9,RANK:530 )
在线值:
发帖
回帖
粉丝
20
强!学习。。
2005-11-15 11:09
0
雪    币: 50
活跃值: (145)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
21
2005-11-15 22:28
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
学习学习学习
2005-11-16 07:51
0
雪    币: 301
活跃值: (300)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
23
看不懂也顶,支持
2005-11-16 08:35
0
雪    币: 260
活跃值: (81)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
24
看不懂还是支持。
2005-11-16 12:19
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
看得这么累不如自己写一个
2005-11-17 13:21
0
游客
登录 | 注册 方可回帖
返回
//