Детальный обзор одного крипт сервиса.
Крипт сервисов в последние время стало ну ооочень много, некоторые из них откровенное *Гуан, некоторые весьма интересны и неординарны в использовании техник сокрытия, обхода эмуляторов, обфускации и т.д. Чтож, давайте посмотрим, что нам может предложить новый сервис ТСа.
Картинки имеют свойство удаляться с файловых хостингов, в связи с этим заливаю их архивом:
http://www.sendspace.com/file/wpd4lw
psw: xss.pro/
ТС прислал 3 криптованных семпла, собстенно цитирую:
Одинаковый размер у всех трех файлов, подумал я, весьма странно.
К тому же стало интересно, что же это за файлы ТС залил в комплекте (._calc_1.exe етц).
Видимо это файлы аттрибутов для файлов под мак ось, я не сторонник мака, так что хз.
Чтож, всё это мелочи, полезли внутрь...
Общие сведенья о PE файле:
PE снифер говорит нам, что это: (E8) Microsoft Visual C++ 9.0 - Visual Studio 2008, ладно.
PE заголовки в порядке.
Присутствует runtime код.
В файлах так же присутствуют дебаг символы)
Что на счет энтропии?
А вот что: Файл 1:
Файл 2:
Секции:
Секции стандартного студийного компилера.
Рерурсы:
Как мы можем видеть, во всех файлах присутствует одинаковое колличество ресурсов.
Ресурсы диалогов #100:
Я тащусь от этой рандомизации
Тут благо немного получше. Контролы выглядят по крайней мере рандомными.
Почему статично только 2 диалога во всех трех файлах мне осталось не ясно.
Ресурсы Strings:
VersionInfo:
Что за TO DO: <...> мне так же не ясно...
FileType: DLL ? (РукаЛицо)
Манифест стандартный из под студии.
Код:
сэмпл 1: (Мэйн хекс рейз походу разобрал криво...)
сэмпл 3:
сэмпл 2:
Как мы можем видеть, активно используются флаги:
А так же инлайновые вставки кода ассемблера:
Опкоды как вы видите не слишком характерны студийному компилеру. Вероятно призваны остановить эмуляторы некоторых АВ продуктов.
Антиэмуляция с помощью GetLastError:
Рандомные апи:
Если их так можно назвать.
И так, судя по коду можно сделать вывод что код не статичный (если стабы собирали не вручную), хоть и генератор кода находится в зачаточном состоянии и использует опкоды и комбинации кода не характерные стандартному компилеру, что не может не отразиться на увеличении баллов у эвристика АВ.
Добавлено в [time]1399118502[/time]
Добавлено в [time]1399118878[/time]
Крипт сервисов в последние время стало ну ооочень много, некоторые из них откровенное *Гуан, некоторые весьма интересны и неординарны в использовании техник сокрытия, обхода эмуляторов, обфускации и т.д. Чтож, давайте посмотрим, что нам может предложить новый сервис ТСа.
Картинки имеют свойство удаляться с файловых хостингов, в связи с этим заливаю их архивом:
http://www.sendspace.com/file/wpd4lw
psw: xss.pro/
ТС прислал 3 криптованных семпла, собстенно цитирую:
Здравствуйте! Высылаю 3 криптованных калькулятора. Хочу сказать сразу - ехе не чист, присутствуют детекты, именно по этой причине я создал тему о предварительном наборе клиентов, т.к. в данный момент наши программисты работают над отладкой и чисткой. Как работы по криптеру будут завершены, будет начата работа с клиентами.
Одинаковый размер у всех трех файлов, подумал я, весьма странно.
К тому же стало интересно, что же это за файлы ТС залил в комплекте (._calc_1.exe етц).
Видимо это файлы аттрибутов для файлов под мак ось, я не сторонник мака, так что хз.
Чтож, всё это мелочи, полезли внутрь...
Общие сведенья о PE файле:
Код:
; Input MD5 : 22EA76FEAF0FDC5C3BBDF7F073C8D60C
; Input CRC32 : 5884E112
; File Name : calc_2.exe
; Format : Portable executable for 80386 (PE)
; Imagebase : 400000
; Section 1. (virtual address 00001000)
; Virtual size : 000111D4 ( 70100.)
; Section size in file : 00011200 ( 70144.)
; Offset to raw data for section: 00000400
; Flags 60000020: Text Executable Readable
; Alignment : default
; OS type : MS Windows
; Application type: Executable 32bit
PE снифер говорит нам, что это: (E8) Microsoft Visual C++ 9.0 - Visual Studio 2008, ладно.
PE заголовки в порядке.
Присутствует runtime код.
В файлах так же присутствуют дебаг символы)
Что на счет энтропии?
А вот что: Файл 1:
Файл 2:
Секции:
Секции стандартного студийного компилера.
Рерурсы:
Как мы можем видеть, во всех файлах присутствует одинаковое колличество ресурсов.
Ресурсы диалогов #100:
Я тащусь от этой рандомизации
Тут благо немного получше. Контролы выглядят по крайней мере рандомными.
Почему статично только 2 диалога во всех трех файлах мне осталось не ясно.
Ресурсы Strings:
Код:
101 &About NQUEdn...
Код:
101 &About CEcuqb...
Код:
101 &About pFjZGpOI...
Что за TO DO: <...> мне так же не ясно...
FileType: DLL ? (РукаЛицо)
Манифест стандартный из под студии.
Код:
сэмпл 1: (Мэйн хекс рейз походу разобрал криво...)
Код:
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);
//----- (00401507) --------------------------------------------------------
signed int __usercall sub_401507<eax>(int a1<ecx>, int a2<ebx>)
{
__asm { lahf }
loc_40B3E7((a1 + 13090743) & 0xC6405C08, dword_408D13, a2 & 0xC7477D);
return 13068065;
}
// 408D13: using guessed type int dword_408D13;
//----- (0040163B) --------------------------------------------------------
int __cdecl sub_40163B()
{
sub_404C8F(0, -402653184);
return dword_40CF2C;
}
// 4010C6: using guessed type int dword_4010C6;
// 40CF2C: using guessed type int dword_40CF2C;
//----- (00401792) --------------------------------------------------------
signed __int64 __cdecl sub_401792()
{
int v1; // edx@1
__asm { lahf }
v1 = *(int *)((char *)&dword_4010C6 + 1);
loc_409F7E(dword_401CE1, v1 & 0xC74721, (dword_40C100 & 0x10844300) + 199, dword_40C100 & 0xD0846300);
return 5784751804415738055i64;
}
// 4010C6: using guessed type int dword_4010C6;
// 401CE1: using guessed type int dword_401CE1;
// 40C100: using guessed type int dword_40C100;
//----- (00401913) --------------------------------------------------------
signed int __cdecl sub_401913()
{
_AL = 0;
__asm
{
lahf
daa
}
((void (__thiscall *)(signed int))dword_401C6D)(193);
return 13067273;
}
// 401C6D: using guessed type int dword_401C6D;
//----- (00401A98) --------------------------------------------------------
unsigned __int64 __cdecl sub_401A98()
{
unsigned int v7; // edx@1
__asm { das }
_CF = 0;
_OF = 0;
_ZF = 0;
_SF = 0;
__asm
{
lahf
pushf
}
sub_406E16();
return __PAIR__(v7, 199) + 4294967296i64;
}
// 4010C6: using guessed type int dword_4010C6;
//----- (00401FF2) --------------------------------------------------------
signed int __fastcall sub_401FF2(int a1, int a2)
{
__asm
{
lahf
lahf
lahf
}
_AL = *(_BYTE *)WinMain + 1;
__asm { daa }
loc_407ED1(
dword_40E700 & 0x73B475DB,
49793,
(unsigned __int8)(*(_BYTE *)WinMain & 0xC4) + 1130655594,
*(_DWORD *)WinMain,
a2);
return -952930975;
}
// 4010C6: using guessed type int dword_4010C6;
// 40E700: using guessed type int dword_40E700;
Код:
//----- (00401000) --------------------------------------------------------
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
int v4; // eax@1
int result; // eax@3
v4 = dword_40F7D2;
do
v4 += 704619264;
while ( !(v4 & 0x5900) );
UnregisterClassA((LPCSTR)0xF43, 0);
result = GetLastError() + 3907;
if ( result == 5318 )
{
__asm
{
bsf ecx, eax
bsr ebx, ecx
}
result = loc_40A58A(_ECX + 1669017712, dword_40C0DA);
}
return result;
}
// 401000: inconsistent function type and number of purged bytes
// 40C0DA: using guessed type int dword_40C0DA;
// 40F7D2: using guessed type int dword_40F7D2;
//----- (00401197) --------------------------------------------------------
signed __int64 __cdecl sub_401197()
{
GetCommandLineA();
GetCommandLineA();
GetCommandLineA();
GetCommandLineA();
sub_402106(911868094);
return 6870362844659698074i64;
}
// 4084B1: using guessed type int dword_4084B1;
// 40C0B2: using guessed type int dword_40C0B2;
// 40CDFF: using guessed type int dword_40CDFF;
//----- (004014E0) --------------------------------------------------------
int __fastcall sub_4014E0(int a1, int a2)
{
return loc_40B67F(0, a2 + 1863229588 - dword_409DF3 - 2054750208, *(_DWORD *)WinMain);
}
// 409DF3: using guessed type int dword_409DF3;
//----- (00401697) --------------------------------------------------------
int __cdecl sub_401697()
{
return loc_409353(dword_40F837 + 1298189679, 1961662519);
}
// 4010B9: using guessed type int __cdecl loc_4010B9(int hInstance, int hPrevInstance, int lpCmdLine, int nShowCmd);
// 40F837: using guessed type int dword_40F837;
//----- (004017F7) --------------------------------------------------------
int __cdecl sub_4017F7()
{
return dword_408537 & loc_40B9BE(1464940494);
}
// 4010B9: using guessed type int __cdecl loc_4010B9(int hInstance, int hPrevInstance, int lpCmdLine, int nShowCmd);
// 408537: using guessed type int dword_408537;
//----- (0040193A) --------------------------------------------------------
int __cdecl sub_40193A()
{
int result; // eax@2
if ( dword_421C70 == -1957299846 )
result = 302994629;
else
result = loc_40A739(-329026324, dword_40BF5C & 0xBE);
return result;
}
Код:
//----- (00401000) --------------------------------------------------------
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
int v4; // eax@0
int result; // eax@2
do
v4 += 704619264;
while ( !(v4 & 0x5900) );
UnregisterClassA((LPCSTR)0xA92, 0);
result = GetLastError() + 2706;
if ( result == 4117 )
{
_EAX = 4272184;
dword_421C70 = (int)((char *)GetProcAddress - 4065);
__asm { lahf }
result = loc_4065DB(2147483647, (unsigned __int64)(64429i64 * _EAX) >> 32);
}
return result;
}
// 401000: inconsistent function type and number of purged bytes
// 40C152: using guessed type int loc_40C152();
// 421C70: using guessed type int dword_421C70;
//----- (004011FF) --------------------------------------------------------
int __cdecl sub_4011FF()
{
__int16 v2; // cx@1
int (__thiscall *v3)(_DWORD); // edx@1
GetCommandLineA();
GetCommandLineA();
GetCommandLineA();
_AL = 0;
__asm { das }
sub_4038A2();
return v3(v2 & 0xFBB2);
}
// 4010F7: using guessed type int __cdecl loc_4010F7(int hInstance, int hPrevInstance, int lpCmdLine, int nShowCmd);
Как мы можем видеть, активно используются флаги:
Код:
_CF = 0;
_OF = 0;
_ZF = 0;
_SF = 0;
А так же инлайновые вставки кода ассемблера:
Код:
__asm
{
lahf
daa
}
__asm
{
bsf ecx, eax
bsr ebx, ecx
}
__asm
{
lahf
lahf
lahf
}
__asm { das }
Антиэмуляция с помощью GetLastError:
Код:
UnregisterClassA((LPCSTR)0xA92, 0);
result = GetLastError() + 2706;
if ( result == 4117 )
{
_EAX = 4272184;
dword_421C70 = (int)((char *)GetProcAddress - 4065);
__asm { lahf }
result = loc_4065DB(2147483647, (unsigned __int64)(64429i64 * _EAX) >> 32);
}
Рандомные апи:
Код:
GetCommandLineA();
GetCommandLineA();
GetCommandLineA();
И так, судя по коду можно сделать вывод что код не статичный (если стабы собирали не вручную), хоть и генератор кода находится в зачаточном состоянии и использует опкоды и комбинации кода не характерные стандартному компилеру, что не может не отразиться на увеличении баллов у эвристика АВ.
Добавлено в [time]1399118502[/time]
Добавлено в [time]1399118878[/time]