易语言核心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期)