滴水加壳作业

解密shell

# include <windows.h>
# include <stdio.h>
int main() {
	// 1.读取当前执行程序,然后取出最后一个节的模块数据进行解密
	char shellpath[256];
	GetModuleFileName(NULL, shellpath, 256);//得到当前模块路径,也就是exe的路径
	FILE* p = fopen(shellpath, "rb");
	//判断打开情况				
	if (!p) {
		printf("文件打开失败\n");
	}
	//判断文件大小				
	fseek(p, 0, SEEK_END);
	int d = ftell(p);
	fseek(p, 0, SEEK_SET);
	//开始读取文件				
	PDWORD ShellBuf = malloc(d);
	memset(ShellBuf, 0, d);
	fread(ShellBuf, 1, d, p);
	if (!fread) {
		printf("读取失败\n");
		free(ShellBuf);
	}
	//壳子的PE
	PIMAGE_DOS_HEADER dos = NULL;
	PIMAGE_NT_HEADERS nt = NULL;
	PIMAGE_FILE_HEADER file = NULL;
	PIMAGE_OPTIONAL_HEADER opt = NULL;
	PIMAGE_SECTION_HEADER jb0 = NULL;
	dos = (PIMAGE_DOS_HEADER)ShellBuf;
	nt = (PIMAGE_NT_HEADERS)((DWORD)ShellBuf + dos->e_lfanew);
	file = (PIMAGE_FILE_HEADER)((DWORD)nt + 4);
	opt = (PIMAGE_OPTIONAL_HEADER)((DWORD)file + 20);
	jb0 = (PIMAGE_SECTION_HEADER)((DWORD)opt + 0xE0);
	printf("%x\n", file->NumberOfSections);

	//开始定位最后一个节,并且返回最后一个节的大小,这里定义一个指针进行接收节的偏移
	int x = (DWORD)file->NumberOfSections - 1;//节的数量减1
	PBYTE Cobin= ((PBYTE)ShellBuf + (jb0 + x)->PointerToRawData);//最后一个节文件中偏移的位置,也就是开始位置
	DWORD SrcSize= (jb0 + x)->SizeOfRawData;//返回最后一个节的大小
	//开始解密
	for (int i = 0; i < SrcSize; i++) {
		Cobin[i] ^= 8888;
	}

	PBYTE SrcBuf = malloc(SrcSize);
	memcpy(SrcBuf, Cobin, SrcSize);
//SRC的PE
	PIMAGE_DOS_HEADER Srcdos = NULL;
	PIMAGE_NT_HEADERS Srcnt = NULL;
	PIMAGE_FILE_HEADER Srcfile = NULL;
	PIMAGE_OPTIONAL_HEADER Srcopt = NULL;
	PIMAGE_SECTION_HEADER Srcjb0 = NULL;
	Srcdos = (PIMAGE_DOS_HEADER)SrcBuf;
	Srcnt = (PIMAGE_NT_HEADERS)((DWORD)SrcBuf + Srcdos->e_lfanew);
	Srcfile = (PIMAGE_FILE_HEADER)((DWORD)Srcnt + 4);
	Srcopt = (PIMAGE_OPTIONAL_HEADER)((DWORD)Srcfile + 20);
	Srcjb0 = (PIMAGE_SECTION_HEADER)((DWORD)Srcopt + 0xE0);

//3、以挂起的形式创建进程:CreateProcess
	STARTUPINFO si = { 0 }; //启动信息结构体
	PROCESS_INFORMATION pi;//进程信息结构体
	ZeroMemory(&pi, sizeof(pi));//给结构体赋初始值全部为0
	si.cb = sizeof(si);//启动信息结构体结构体的大小,必须写
	BOOL res = CreateProcess(
		shellpath,// 应用程序名(可执行文件)
		NULL,				// 命令行参数
		NULL,				 // 进程对象的安全属性
		NULL,				// 主线程对象的安全属性
		FALSE,				// 指示子进程是否继承父进程的句柄
		CREATE_SUSPENDED,	// 进程创建标志,控制台分开,CREATE_SUSPENDED这个参数是以挂起的形式创建一个新的进程
		NULL,				// 新的环境变量块指针
		NULL,				 // 当前目录的路径
		&si,				 // 启动信息结构体
		&pi					// 进程信息结构体
	);
	CONTEXT contest;//创建存储线程结构体
	contest.ContextFlags = CONTEXT_FULL;//获取某一段寄存器的值,要哪段就写哪段
	BOOL ok = GetThreadContext(pi.hThread, &contest);//获取线程上下文内容,也就是寄存器
	// 加载 ntdll.dll
	HMODULE hNtdll = LoadLibrary("ntdll.dll");
	if (hNtdll == NULL) {
		return 1;
	}
	typedef DWORD(WINAPI* _TZwUnmapViewOfSection)(HANDLE, PVOID);
	_TZwUnmapViewOfSection pZwUnmapViewOfSection = (_TZwUnmapViewOfSection)GetProcAddress(hNtdll, "ZwUnmapViewOfSection");
	NTSTATUS status = pZwUnmapViewOfSection(pi.hProcess, (PVOID)opt->ImageBase);
	printf("卸载成功:%d\n", status);

	//将SRC进程拉伸
	PBYTE NewSrcBuf = malloc(Srcopt->SizeOfImage);
	memset(NewSrcBuf, 0, Srcopt->SizeOfImage);
	//移动头部
	memcpy(NewSrcBuf, SrcBuf, Srcopt->SizeOfHeaders);
	printf("节数:%d\n", Srcfile->NumberOfSections);
	printf("大小:%d\n", Srcopt->SizeOfImage);
	//接下来复制节,节得复制需要根据节表提供得信息进行复制,复制次数等于节得个数
	for (int i = 0; i < Srcfile->NumberOfSections; i++) {//从文件buf 复制到imagebuf
		memcpy((LPVOID)(((DWORD)NewSrcBuf) + (Srcjb0 + i)->VirtualAddress), (LPVOID)((DWORD)SrcBuf + (Srcjb0 + i)->PointerToRawData), (Srcjb0 + i)->SizeOfRawData);
	}
	//获取SRC的IMAGEBASE 
	LONGLONG SrcImageBase = Srcopt->ImageBase;
	LONGLONG SrcImageBufferSize = Srcopt->SizeOfImage;
	// 在傀儡进程的SRC的ImageBase处申请SizeOfImage大小的内存	
	LPVOID pImageBase = VirtualAllocEx(pi.hProcess, (LPVOID)SrcImageBase, SrcImageBufferSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	//将SRC内存镜像复制到傀儡进程4GB中	
	if (NULL == WriteProcessMemory(pi.hProcess, (LPVOID)SrcImageBase, NewSrcBuf, SrcImageBufferSize, NULL))
	{
		printf("写入源程序内存镜像失败\n");
		TerminateThread(pi.hThread, 0);
		return -1;
	}
	contest.Eax = Srcopt->AddressOfEntryPoint + SrcImageBase;
	PDWORD ebx8 = contest.Ebx + 8;
	WriteProcessMemory(pi.hProcess, &ebx8, &SrcImageBase, 4, NULL);
	SetThreadContext(pi.hThread, &contest);
	// 恢复线程	
	ResumeThread(pi.hThread);
	free(SrcBuf);
	free(NewSrcBuf);
	system("pause");
	return 0;
}

加密部分

#include<stdio.h>
#include<windows.h>
#define IMAGE_SIZEOF_SHORT_NAME
#define out			"H:\\滴水工具\\IPMsg3\\加密后.exe"	

PDWORD ReadFile1(IN LPSTR file, OUT PDWORD* BUF) {

	//读取文件				
	FILE* p = fopen(file, "rb");
	//判断打开情况				
	if (!p) {
		printf("文件打开失败\n");
	}
	//判断文件大小				
	fseek(p, 0, SEEK_END);
	int d = ftell(p);
	fseek(p, 0, SEEK_SET);
	//开始读取文件				
	char* buf = malloc(d);
	memset(buf, 0, d);
	fread(buf, 1, d, p);
	if (!fread) {
		printf("读取失败\n");
		free(buf);
	}
	*BUF = buf;
	buf = NULL;
	fclose(p);
	return d;



}

PVOID ADDjie(IN PDWORD SHELLBUF, IN DWORD filesize, IN DWORD shellsize, IN PDWORD FILEBUF) {
	if (!SHELLBUF) {
		printf("加载失败\n");
		return 0;
	}
	PIMAGE_DOS_HEADER dos = NULL;
	PIMAGE_NT_HEADERS nt = NULL;
	PIMAGE_FILE_HEADER file = NULL;
	PIMAGE_OPTIONAL_HEADER opt = NULL;
	PIMAGE_SECTION_HEADER jb0 = NULL;
	dos = (PIMAGE_DOS_HEADER)SHELLBUF;
	nt = (PIMAGE_NT_HEADERS)((DWORD)SHELLBUF + dos->e_lfanew);
	file = (PIMAGE_FILE_HEADER)((DWORD)nt + 4);
	opt = (PIMAGE_OPTIONAL_HEADER)((DWORD)file + 20);
	jb0 = (PIMAGE_SECTION_HEADER)((DWORD)opt + 0xE0);
	//申请内存时多D
	int d = filesize + shellsize;

	PDWORD NEWshellbuf = malloc(d);
	memset(NEWshellbuf, 0, d);

	//修改新增节的数据

	file->NumberOfSections = (DWORD)file->NumberOfSections + 1;
	DWORD T = ((DWORD)file->NumberOfSections - 1);
	opt->SizeOfImage = (DWORD)opt->SizeOfImage + filesize;
	(jb0 + T)->Name[IMAGE_SIZEOF_SHORT_NAME 0] = 0x2E;
	(jb0 + T)->Name[IMAGE_SIZEOF_SHORT_NAME 1] = 0x74;
	(jb0 + T)->Name[IMAGE_SIZEOF_SHORT_NAME 2] = 0x74;
	(jb0 + T)->Name[IMAGE_SIZEOF_SHORT_NAME 3] = 0x74;
	(jb0 + T)->Name[IMAGE_SIZEOF_SHORT_NAME 4] = 0x74;
	(jb0 + T)->Misc.VirtualSize = filesize;
	(jb0 + T)->VirtualAddress = (DWORD)(jb0 + (T - 1))->VirtualAddress + 0x1000;
	//(jb0 + T)->VirtualAddress = 0x20000;
	(jb0 + T)->SizeOfRawData = filesize;
	(jb0 + T)->PointerToRawData = (DWORD)(jb0 + (T - 1))->PointerToRawData + (DWORD)(jb0 + (T - 1))->SizeOfRawData;
	((jb0 + T))->Characteristics = 0x60000020;
	//memcpy(NEWshellbuf, SHELLBUF, shellsize);//这里是移动壳子,也就是shell
	memcpy(NEWshellbuf, SHELLBUF, shellsize);
	//这里原本的程序移动结束,现在开始移动加密数据,移动到最后一个节
	//存储位置是最后一个节的文件 偏移开始
	LPVOID cobin = ((DWORD)NEWshellbuf + shellsize);
	//复制位置SHELLBUF
	//复制大小D
	memcpy(cobin, FILEBUF, filesize);//这里移动SRC 移动到最后一个节得开始位置 移动大小就是filesize
   
	//存盘

	MemeryTOFile(NEWshellbuf, d, out);

}
void EnterSource(IN PBYTE SIZE, OUT PBYTE fileBUF) {

	//简单的异或加密,循环加密
	for (int i = 0; i < SIZE; i++) {
		fileBUF[i] ^= 8888;
	}
	printf("加密成功\n");
	printf("%d\n", SIZE);
}

BOOL MemeryTOFile(IN LPVOID Buffer, IN size_t size, OUT LPSTR File) {
	FILE* p1 = NULL;
	p1 = fopen(File, "wb");
	if (!p1) {
		printf("文件打开失败\n");
	}
	fwrite(Buffer, size, 1, p1);
	if (!fwrite) {
		printf("存盘失败\n");
		free(Buffer);
	}
	else
	{
		printf("存盘成功\n");
	}
	fclose(p1);
	p1 = NULL;
	return 0;

}

int main() {
	char  filename_src[256] = "H:\\滴水工具\\IPMsg3\\ipmsg.exe";
	char  filename_shell[256] = "H:\\C语言学习\\加壳项目解密部分\\Debug\\加壳项目解密部分.exe";
	//char  filename_shell[256] = "H:\\C语言学习\\解密1\\Debug\\解密1.exe";
	//char  filename_shell[256] = "H:\\C语言学习\\解密壳部分\\Debug\\解密壳部分.exe";
	PDWORD filebuf = NULL;
	DWORD filesize = NULL;
	PDWORD shellbuf = NULL;
	DWORD shellsize = NULL;

	filesize = ReadFile1(filename_src, &filebuf);
	shellsize=ReadFile1(filename_shell, &shellbuf);


	//加密
	EnterSource(filesize, filebuf);
	//放到节后面
	ADDjie(shellbuf, filesize, shellsize, filebuf);
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值