📄 erika.c
字号:
mov esi, dword ptr [esp+0x28]
lods byte ptr [esi]
mov edx, eax
copy:
lods dword ptr [esi]
mov edi, eax
add edi, ebp
lods dword ptr [esi]
mov ecx, eax
rep movsb ;恢复各段
dec edx
jnz copy
pop ecx
pop edx
pop eax
mov edi, [esp]
test eax, eax
je noe8e9;
nexte8e9:
mov al, byte ptr [edi]
inc edi
sub al, 0xe8
cmp al, 1
ja nexte8e9
mov eax, [edi]
cmp al, dl
jne nexte8e9
xor al, al
bswap eax
add eax, [esp]
sub eax, edi
stos dword ptr [edi] ;E8 E9过滤
loop nexte8e9
noe8e9:
push ebp
nextdll:
lods dword ptr [esi]
test eax, eax
je over
mov edi, eax
add edi, [esp]
push esi
call dword ptr [ebx]
mov ebp, eax
dllname:
lods byte ptr [esi]
test al, al
jnz dllname
apiname: ;输入表恢复
lods dword ptr [esi]
test eax, eax
je nextdll
sub esi, 0x04
lods dword ptr [esi]
test eax, 0x80000000
jnz ordinal
sub esi, 0x04
push esi
push ebp
call dword ptr [ebx+0x04]
stos dword ptr [edi]
jmp dllname
ordinal:
and eax, 0x7FFFFFFF
push eax
push ebp
call dword ptr [ebx+0x04]
stos dword ptr [edi]
jmp apiname
over:
pop ebp
pop edi
ret
}
}
void __declspec(naked) loader_end()
{
__asm
{
lea ebx, [edi-0x04]
reloc:
xor eax, eax
lods byte ptr [esi]
test al, al
je over
cmp al, 0xEF
ja reloc2
reloc1:
add ebx, eax
add [ebx], edi
jmp reloc
reloc2:
and al, 0x0F
shl eax, 0x10
lods word ptr [esi]
test eax, eax
jnz reloc1
lods dword ptr [esi]
jmp reloc1
over:
ret
}
}
void __declspec(naked) loader_end2()
{
__asm __emit 0xCC
}
///////////////////////////////////////////////////////////////
void MakeShell()
{
//这里再不写点注释以后就记不清了
DWORD dwLastSection;
DWORD dwSizeOfLoader;
DWORD dwSizeOfHeader;
DWORD dwSizeOfFile;
DWORD dwSize;
DWORD i;
//通过最后一个区段信息计算壳段起始地址
dwLastSection = PE->FileHeader.NumberOfSections-1;
AddrOfShell = (SH+dwLastSection)->VirtualAddress + (SH+dwLastSection)->Misc.VirtualSize;
AddrOfShell = (AddrOfShell+0xFFF)/0x1000*0x1000;
dwSizeOfLoader = (DWORD)loader_end - (DWORD)loader;
if (MapOfReloc != NULL && SizeOfReloc != 0)
dwSizeOfLoader += (DWORD)loader_end2 - (DWORD)loader_end - 1;
//壳段总长
SizeOfShell = SizeOfRSRC + sizeof(ShellIAT) + dwSizeOfLoader + SizeOfPacked + SizeOfTLS;
//dll重定位
if (MapOfReloc != NULL && SizeOfReloc != 0)
SizeOfShell += 0x0C;
MapOfShell = VirtualAlloc(NULL, SizeOfShell, MEM_COMMIT, PAGE_READWRITE);
dwSize = 0;
//先写入资源
if (MapOfRSRC != 0 && SizeOfRSRC != 0)
{
if (CountOfICON != 0 && ICONOffset != NULL)
{
for (i=0; i<CountOfICON; i++)
{
*(LPDWORD)(*(LPDWORD)(ICONOffset+i*8+4)) += AddrOfShell;
}
}
if (GICONOffset != 0)
*GICONOffset += AddrOfShell;
if (VERSNOffset != 0)
*VERSNOffset += AddrOfShell;
if (XML18Offset != 0)
*XML18Offset += AddrOfShell;
memcpy(MapOfShell+dwSize, MapOfRSRC, SizeOfRSRC);
dwSize += SizeOfRSRC;
}
//再是输入表
memcpy(MapOfShell+dwSize, ShellIAT, sizeof(ShellIAT));
*(LPDWORD)(MapOfShell+dwSize+0x0C) += AddrOfShell+dwSize;
*(LPDWORD)(MapOfShell+dwSize+0x10) += AddrOfShell+dwSize;
*(LPDWORD)(MapOfShell+dwSize+0x70) += AddrOfShell+dwSize;
*(LPDWORD)(MapOfShell+dwSize+0x74) += AddrOfShell+dwSize;
*(LPDWORD)(MapOfShell+dwSize+0x78) += AddrOfShell+dwSize;
*(LPDWORD)(MapOfShell+dwSize+0x7C) += AddrOfShell+dwSize;
dwSize += sizeof(ShellIAT);
//再是loader
memcpy(MapOfShell+dwSize, &loader, (DWORD)loader_end - (DWORD)loader);
*(LPDWORD)(MapOfShell+dwSize+0x02) = AddrOfShell + dwSize + 19;
*(LPDWORD)(MapOfShell+dwSize+0x07) = PE->OptionalHeader.ImageBase;
*(LPDWORD)(MapOfShell+dwSize+0x0F) = SH->VirtualAddress
+ sizeof(EP) + sizeof(Aplib) + sizeof(LZMA);
dwSize += (DWORD)loader_end - (DWORD)loader;
if (MapOfReloc != NULL && SizeOfReloc != 0)
{
memcpy(MapOfShell+dwSize-1, &loader_end, (DWORD)loader_end2-(DWORD)loader_end);
dwSize += (DWORD)loader_end2-(DWORD)loader_end-1;
}
//再是压缩数据
memcpy(MapOfShell+dwSize, MapOfPack+0x0E, SizeOfPacked);
dwSize += SizeOfPacked;
//再是新重定位表
if (MapOfReloc != NULL && SizeOfReloc != 0)
{
i = AddrOfShell + SizeOfRSRC + sizeof(ShellIAT) + 0x07;
*(LPDWORD)(MapOfShell+dwSize+0x00) = i/0x1000*0x1000;
*(LPDWORD)(MapOfShell+dwSize+0x04) = 0x0C;
*(LPWORD)(MapOfShell+dwSize+0x08) = 0x3000 | (i%0x1000);
*(LPWORD)(MapOfShell+dwSize+0x00A) = 0;
}
//再是TLS
if (MapOfTLS != NULL && SizeOfTLS != 0)
{
memcpy(MapOfShell+dwSize, MapOfTLS, SizeOfTLS);
dwSize += SizeOfTLS;
}
//计算新的PE头的长度
dwSizeOfHeader = 4 + 40 + (DWORD)&(SH+dwLastSection)->Characteristics;
dwSizeOfHeader -= (DWORD)MapOfFile;
dwSizeOfHeader = (dwSizeOfHeader+0x1FF)/0x200*0x200;
PE->OptionalHeader.SizeOfHeaders = dwSizeOfHeader;
//更新各个新区段
dwSizeOfFile = dwSizeOfHeader;
for (i=0; i<PE->FileHeader.NumberOfSections; i++)
{
if (i==0)
{
memset(MapOfFile+(SH+i)->VirtualAddress, 0, 0x600);
memcpy(MapOfFile+(SH+i)->VirtualAddress, EP, sizeof(EP));
memcpy(MapOfFile+(SH+i)->VirtualAddress+sizeof(EP), Aplib, sizeof(Aplib));
memcpy(MapOfFile+(SH+i)->VirtualAddress+sizeof(EP)+sizeof(Aplib), LZMA, sizeof(LZMA));
memcpy(MapOfFile+(SH+i)->VirtualAddress+0x600-sizeof(INFO), INFO, sizeof(INFO));
*(LPDWORD)(MapOfFile+(SH+i)->VirtualAddress+1) = PE->OptionalHeader.ImageBase + AddrOfShell + SizeOfRSRC + sizeof(ShellIAT) + 1;
(SH+i)->PointerToRawData = dwSizeOfFile;
(SH+i)->SizeOfRawData = 0x600;
dwSizeOfFile += 0x600;
continue ;
}
(SH+i)->PointerToRawData = dwSizeOfFile;
(SH+i)->SizeOfRawData = 0;
}
//增加壳段到PE头中
(SH+i)->VirtualAddress = AddrOfShell;
(SH+i)->PointerToRawData = dwSizeOfFile;
(SH+i)->SizeOfRawData = (dwSize+0x1FF)/0x200*0x200;
dwSizeOfFile += dwSize;
dwSize = (dwSize+0xFFF)/0x1000*0x1000;
(SH+i)->Misc.VirtualSize = dwSize;
(SH+i)->Characteristics = 0xE00000E0;
strcpy((SH+i)->Name, ".shoooo");
//更新总映象大小和区段数等等
PE->OptionalHeader.SizeOfImage = AddrOfShell+dwSize;
PE->FileHeader.NumberOfSections++;
PE->OptionalHeader.FileAlignment = 0x200;
PE->OptionalHeader.SectionAlignment = 0x1000;
//填壳信息
ShellInfo = (LPDWORD)(MapOfFile+SH->VirtualAddress+sizeof(EP)+sizeof(Aplib)+sizeof(LZMA));
*(ShellInfo+0) = PE->OptionalHeader.AddressOfEntryPoint;//OEP
*(ShellInfo+1) = AddrOfShell + SizeOfRSRC + sizeof(ShellIAT) - 0x14;//壳IAT
*(ShellInfo+2) = 0;
*(ShellInfo+3) = SH->VirtualAddress + sizeof(EP)+sizeof(Aplib); //LZMA块
*(ShellInfo+4) = SH->VirtualAddress + sizeof(EP); //Aplib解压函数
*(ShellInfo+5) = SizeOfPack;//解压后的数据长度
*(ShellInfo+6) = SizeOfPacked; //压缩包的长度
*(ShellInfo+7) = AddrOfShell + SizeOfShell - SizeOfPacked - SizeOfTLS; //压缩数据起始
if (MapOfReloc != NULL && SizeOfReloc != 0)
*(ShellInfo+7) -= 0x0C;
*(ShellInfo+8) = SH->VirtualAddress; //第一段起始
if (MagicMark != 0xFE)
*(ShellInfo+9) = 1;
else
*(ShellInfo+9) = 0;
*(ShellInfo+10) = MagicMark;
*(ShellInfo+11) = MagicNumber;
//更新ep
PE->OptionalHeader.AddressOfEntryPoint = SH->VirtualAddress;
if (MapOfReloc != NULL && SizeOfReloc != 0)
PE->OptionalHeader.AddressOfEntryPoint = AddrOfShell + SizeOfRSRC + sizeof(ShellIAT) + 1;
//更新资源表和输入表
PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = AddrOfShell+SizeOfRSRC;
PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = sizeof(ShellIAT);
if (MapOfRSRC != NULL && SizeOfRSRC != 0)
{
PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = AddrOfShell;
PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = SizeOfRSRC;
}
if (MapOfTLS != NULL && SizeOfTLS != 0)
{
PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = AddrOfShell+SizeOfShell-SizeOfTLS;
PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = SizeOfTLS;
}
if (MapOfReloc != NULL && SizeOfReloc != 0)
{
PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = AddrOfShell+SizeOfShell-0x0C-SizeOfTLS;;
PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0x0C;
}
//清段垃圾表
PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = 0;
PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = 0;
PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = 0;
PE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size = 0;
return ;
}
///////////////////////////////////////////////////////////////
void OutputFile(HANDLE hFile)
{
DWORD dwWritten;
int i;
WriteFile(hFile, MapOfFile, PE->OptionalHeader.SizeOfHeaders, &dwWritten, NULL);
for (i=0; i<PE->FileHeader.NumberOfSections-1; i++)
{
WriteFile(hFile, (SH+i)->VirtualAddress+MapOfFile, (SH+i)->SizeOfRawData, &dwWritten, NULL);
}
WriteFile(hFile, MapOfShell, (SizeOfShell+0x1FF)/0x200*0x200, &dwWritten, NULL);
if (MapOfOverlay !=0 && SizeOfOverlay !=0)
{
WriteFile(hFile, MapOfOverlay, SizeOfOverlay, &dwWritten, NULL);
}
}
///////////////////////////////////////////////////////////////
void jobdone()
{
memset(szFileName, 0, sizeof(szFileName));
if (MapOfFile != NULL)
{
VirtualFree(MapOfFile, 0, MEM_RELEASE);
MapOfFile = NULL;
}
if (MapOfOverlay != NULL)
{
VirtualFree(MapOfOverlay, 0, MEM_RELEASE);
MapOfOverlay = NULL;
}
SizeOfOverlay = 0;
if (MapOfIAT != NULL)
{
VirtualFree(MapOfIAT, 0, MEM_RELEASE);
MapOfIAT = NULL;
}
SizeOfIAT = 0;
if (MapOfRSRC != NULL)
{
VirtualFree(MapOfRSRC, 0, MEM_RELEASE);
MapOfRSRC = NULL;
}
SizeOfRSRC = 0;
CountOfICON = 0;
if (ICONOffset != NULL)
{
VirtualFree(ICONOffset, 0, MEM_RELEASE);
ICONOffset = NULL;
}
GICONOffset = NULL;
VERSNOffset = NULL;
XML18Offset = NULL;
if (MapOfTLS != NULL)
{
VirtualFree(MapOfTLS, 0, MEM_RELEASE);
MapOfTLS = NULL;
}
SizeOfTLS = 0;
if (MapOfReloc != NULL)
{
VirtualFree(MapOfReloc, 0, MEM_RELEASE);
MapOfReloc = NULL;
}
SizeOfReloc = 0;
if (MapOfPack != NULL)
{
VirtualFree(MapOfPack, 0, MEM_RELEASE);
MapOfPack = NULL;
}
SizeOfPack = 0;
SizeOfPacked = 0;
if (MapOfShell != NULL)
{
VirtualFree(MapOfShell, 0, MEM_RELEASE);
MapOfShell = NULL;
}
AddrOfShell = 0;
SizeOfShell = 0;
ShellInfo = NULL;
PE = NULL;
SH = NULL;
bDLL = FALSE;
}
///////////////////////////////////////////////////////////////
void KByS()
{
HANDLE hFile;
hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
if (bChinese)
strcpy(szMessage, "打开文件失败");
else
strcpy(szMessage, "fail to open the file");
return;
}
if (!IsPE(hFile))
{
if (bChinese)
strcpy(szMessage, "无效PE");
else
strcpy(szMessage, "invalid PE file");
CloseHandle(hFile);
return;
}
MapFile(hFile);
OverlayFile(hFile);
CloseHandle(hFile);
SizeOfIAT = GetSizeIAT();
FuckIAT();
GetIconRSRC();
FuckRSRC();
FuckTLS();
FuckReloc();
MakeReloc();
FuckE8E9();
FuckSection();
PackSection();
MakeShell();
BackupSrcFile(szFileName);
hFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
if (bChinese)
strcpy(szMessage, "写入文件失败");
else
strcpy(szMessage, "fail to write the file");
jobdone();
return;
}
OutputFile(hFile);
CloseHandle(hFile);
jobdone();
if (bChinese)
strcpy(szMessage, "压缩完成");
else
strcpy(szMessage, "job done");
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -