首页
社区
课程
招聘
[求助]看滴水教程,写壳遇到一个问题
发表于: 2015-11-11 22:08 11215

[求助]看滴水教程,写壳遇到一个问题

2015-11-11 22:08
11215
ps:首先谢谢滴水,谢谢他们贡献出免费的教程(质量真的还不错),也希望滴水能够出更多的有质量的进阶教程(因为要工作没法实地,只能自学),我也会购买的。
我建立一个群“滴水视频交流”,自学的朋友可以加,一起探讨,群号:495134543,请备注:看雪
正题和问题:
1. 我看滴水的视频然后写了一个壳,程序加壳后会报错

2. 加壳过程(kiwifruitshell.exe,中可以选择壳源和被加壳程序)
a. 在壳源加一个区段
b. 把被加壳的程序作为数据塞入这个区段

3. 解壳过程
a. 执行加壳后的程序,KiwifruitShell.exe_shell.exe
b. 判断是否有.kiwi区段,没有直接退出
c. 取出这个区段内容,然后new一个buff,然后把区段中的内容(其实是整个PE文件)按照内存中的样子拉伸,然后拷贝new出来的buff中
d. 阻塞创建一个进程,并且获取这个进程和主线程句柄
e. 根据获得的进程句柄,把c步骤拉中new出来的buff,拷贝到刚刚创建的进程空间中,从imagebase开始拷贝
f. 根据获得的线程句柄,把线程contex结构中的eip,设置为 ImageBase + OEP
g.让刚刚创建出来的进程中的主线程解除阻塞继续执行,然后就有上图中的报错

2. 环境是,win764 vs2010
3. 原因在什么地方了?
壳源代码,整个工程最后面会附加上:
#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include "string.h"
#include "MyShell.h"

#define  MAX_HEADER_SIZE 8192  //最大的pe头,是个估算值
#define OUT_PUT_BUFF_SIZE 4097 //调试信息最大的输出缓冲区

//
#define STATUS_SUCCESS                   0x00000000

typedef LONG NTSTATUS;
typedef NTSTATUS  (WINAPI *lfpZwUnmapViewOfSection)(IN HANDLE  ProcessHandle,IN PVOID  BaseAddress);


//
BOOL FileBuff2ImageBuff(BYTE *pbyFileBuff, DWORD dwFilebuffSize,  BYTE *pbyImageBuff, DWORD dwImageSize);

//
void  OutputDebugStringF(const char *fmt, ...);
#ifdef _DEBUG
#define  DbgPrintf OutputDebugStringF
#else
#define  DbgPrintf 
#endif

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	HANDLE hSelfProcess = NULL;
	HANDLE hTargetProcess = NULL;
	BYTE *pbyFileBuff = NULL;
	BYTE *pbyImageBuff = NULL;
	HMODULE hNTModule = NULL;
	//
	BYTE byArryReadBuff[MAX_HEADER_SIZE] = {0};
	DWORD dwNumRead;
	hSelfProcess=OpenProcess(
			 //PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, 
			 PROCESS_ALL_ACCESS,
			 FALSE, 
			 GetCurrentProcessId());
	ReadProcessMemory(hSelfProcess, hInstance, byArryReadBuff, 8192, &dwNumRead);
	PIMAGE_DOS_HEADER pDosHeader= (PIMAGE_DOS_HEADER)byArryReadBuff;
	if( IMAGE_DOS_SIGNATURE != pDosHeader->e_magic) goto CLEAN;
	PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)(byArryReadBuff + pDosHeader -> e_lfanew);
	if( IMAGE_NT_SIGNATURE != pNTHeader->Signature ) goto CLEAN;
	PIMAGE_FILE_HEADER pFileHeader = &pNTHeader->FileHeader;
	PIMAGE_OPTIONAL_HEADER pOptHeader = &pNTHeader->OptionalHeader;
	PIMAGE_SECTION_HEADER pFirstSection = IMAGE_FIRST_SECTION(pNTHeader);
	PIMAGE_SECTION_HEADER pLastSection = &pFirstSection[pFileHeader->NumberOfSections - 1];
	char szSectionName[MAX_PATH] = {0};
	memcpy(szSectionName, pLastSection->Name, IMAGE_SIZEOF_SHORT_NAME);
	//
	if(0 !=strcmp(szSectionName, ".kiwi")) goto CLEAN;
	MessageBox(NULL, _T("被加壳了,点击继续执行"), _T("提示"), MB_OK);
	//
	char szFilePath[MAX_PATH] = {0};
	GetModuleFileName(NULL, szFilePath, MAX_PATH - 1 );
	//
	STARTUPINFO startupInfo;  
	PROCESS_INFORMATION processInfo;  
	ZeroMemory(&startupInfo, sizeof(startupInfo) );  
	startupInfo.cb = sizeof(startupInfo);
	ZeroMemory(&processInfo, sizeof(processInfo));
	//
	BOOL bCreateProcessFlag = 
		CreateProcess(
		NULL,
		szFilePath,
		NULL,
		NULL,
		FALSE,
		CREATE_SUSPENDED,
		NULL,
		NULL,
		&startupInfo,
		&processInfo);
	if(!bCreateProcessFlag) goto CLEAN;
	DWORD dwCodeAddress= pLastSection->VirtualAddress;
	DWORD dwCodeSize =  pLastSection->SizeOfRawData;
	pbyFileBuff = new BYTE[dwCodeSize];
	if(NULL == pbyFileBuff) goto CLEAN;
	ZeroMemory(pbyFileBuff, dwCodeSize);
	ReadProcessMemory(
		hSelfProcess, 
		(LPVOID)(pOptHeader->ImageBase + dwCodeAddress),
		pbyFileBuff,
		dwCodeSize, 
		&dwNumRead
		);
	if(0 == dwNumRead || dwNumRead <dwCodeSize) goto CLEAN;
	for(DWORD i = 0; i < dwCodeSize; i++)
	{
		pbyFileBuff[i] ^= 0xCE;
	}
	//
	hTargetProcess=OpenProcess(
		PROCESS_ALL_ACCESS, 
		FALSE, 
		processInfo.dwProcessId);
	if(NULL == hTargetProcess) goto CLEAN;
	//
	PIMAGE_DOS_HEADER pTargetDosHeader= (PIMAGE_DOS_HEADER)pbyFileBuff;
	if( IMAGE_DOS_SIGNATURE != pTargetDosHeader->e_magic) goto CLEAN;
	PIMAGE_NT_HEADERS pTargetNTHeader = (PIMAGE_NT_HEADERS)(pbyFileBuff + pTargetDosHeader -> e_lfanew);
	if( IMAGE_NT_SIGNATURE != pTargetNTHeader->Signature ) goto CLEAN;
	PIMAGE_FILE_HEADER pTargetFileHeader = &pTargetNTHeader->FileHeader;
	PIMAGE_OPTIONAL_HEADER pTargetOptHeader = &pTargetNTHeader->OptionalHeader;
	DWORD dwImageBuffSize = pTargetOptHeader->SizeOfImage;
	//
	pbyImageBuff = new BYTE[dwImageBuffSize];
	if(NULL == pbyImageBuff) goto CLEAN;
	BOOL bF2I = FileBuff2ImageBuff(pbyFileBuff, dwCodeSize,  pbyImageBuff, dwImageBuffSize);
	if(! bF2I) goto CLEAN;
	//卸载程序
	hNTModule = LoadLibrary("ntdll.dll"); 
	if(NULL == hNTModule) goto CLEAN;
	lfpZwUnmapViewOfSection ZwUnmapViewOfSection = NULL;
	ZwUnmapViewOfSection = (lfpZwUnmapViewOfSection)GetProcAddress( 
		hNTModule,
		"ZwUnmapViewOfSection"); 
	NTSTATUS  lStatus = ZwUnmapViewOfSection(hTargetProcess, (LPVOID)pOptHeader->ImageBase);
	DbgPrintf("lstatus:%d", lStatus);
	if(STATUS_SUCCESS != lStatus) goto CLEAN;
	//
	DWORD dwOldProtect, dwTmp;
	VirtualProtectEx(
		hTargetProcess,
		(LPVOID)pTargetOptHeader->ImageBase,
		pTargetOptHeader->SizeOfImage,
		PAGE_EXECUTE_READWRITE,
		&dwOldProtect
		);
	VirtualFreeEx(
		hTargetProcess, 
		(LPVOID)pTargetOptHeader->ImageBase,
		pTargetOptHeader->SizeOfImage,
		MEM_DECOMMIT
		);
	LPVOID lpAlloc = VirtualAllocEx(
		hTargetProcess,
		(LPVOID)pTargetOptHeader->ImageBase,
		pTargetOptHeader->SizeOfImage,
		MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
	if(NULL == lpAlloc) goto CLEAN;
	DWORD dwNumWrite;
	BOOL bWrite = WriteProcessMemory(
		hTargetProcess,
		(LPVOID)pTargetOptHeader->ImageBase,
		pbyImageBuff,
		dwImageBuffSize,
		&dwNumWrite);
	VirtualProtectEx(
		hTargetProcess,
		(LPVOID)pTargetOptHeader->ImageBase,
		pTargetOptHeader->SizeOfImage,
		dwOldProtect,
		&dwTmp
		);
	if(!bWrite) goto CLEAN;
	//
	CONTEXT threadContext;
	ZeroMemory(&threadContext, sizeof(threadContext));
	threadContext.ContextFlags = CONTEXT_CONTROL;
	if(! GetThreadContext(processInfo.hThread, &threadContext)) goto CLEAN;
	threadContext.Eip = pTargetOptHeader->ImageBase + pTargetOptHeader->AddressOfEntryPoint;
	threadContext.ContextFlags = CONTEXT_CONTROL;     // 重新设置ContextFlags
	SetThreadContext(processInfo.hThread, &threadContext);  
	//
	ResumeThread(processInfo.hThread);

CLEAN:
	if(NULL != hSelfProcess) CloseHandle(hSelfProcess);
	if(NULL != hTargetProcess) CloseHandle(hTargetProcess);
	if(NULL != pbyFileBuff) delete [] pbyFileBuff;
	if(NULL != pbyImageBuff) delete [] pbyImageBuff;
	if(NULL != hNTModule) FreeLibrary(hNTModule);

	return 0;
}

// @doc 把文件在内存中拉伸
BOOL FileBuff2ImageBuff(BYTE *pbyFileBuff, DWORD dwFilebuffSize,  BYTE *pbyImageBuff, DWORD dwImageSize)
{
	ZeroMemory(pbyImageBuff, dwImageSize);
	PIMAGE_DOS_HEADER pDosHeader= (PIMAGE_DOS_HEADER)pbyFileBuff;
	if( IMAGE_DOS_SIGNATURE != pDosHeader->e_magic) goto FINSH_ERROR;
	PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)(pbyFileBuff + pDosHeader -> e_lfanew);
	if( IMAGE_NT_SIGNATURE != pNTHeader->Signature ) goto FINSH_ERROR;
	PIMAGE_FILE_HEADER pFileHeader = &pNTHeader->FileHeader;
	PIMAGE_OPTIONAL_HEADER pOptHeader = &pNTHeader->OptionalHeader;
	//拷贝pe所有的头信息
	memcpy(pbyImageBuff, pbyFileBuff, pOptHeader->SizeOfHeaders);
	//拷贝各个节区
	PIMAGE_SECTION_HEADER pFirstSection = IMAGE_FIRST_SECTION(pNTHeader);
	for(DWORD i = 0; i < pFileHeader->NumberOfSections; i++)
	{
		DWORD dwCpySize= pFirstSection[i].SizeOfRawData >= pFirstSection[i].Misc.VirtualSize? pFirstSection[i].SizeOfRawData:pFirstSection[i].Misc.VirtualSize;
		memcpy(
			pbyImageBuff + pFirstSection[i].VirtualAddress,
			pbyFileBuff + pFirstSection[i].PointerToRawData,
			dwCpySize);
	}
	goto FINSH_OK;
FINSH_OK:
	return TRUE;
FINSH_ERROR:
	return FALSE;
}

//调试打印
void  OutputDebugStringF(const char *fmt, ...)
{
	va_list vlArgs;
	char *strBuf = (char*)GlobalAlloc(GPTR, OUT_PUT_BUFF_SIZE);
	ZeroMemory(strBuf, OUT_PUT_BUFF_SIZE);
	va_start(vlArgs, fmt);
	_vsnprintf_s(strBuf, OUT_PUT_BUFF_SIZE - 1, OUT_PUT_BUFF_SIZE -1, fmt, vlArgs);
	va_end(vlArgs);
	strcat_s(strBuf, OUT_PUT_BUFF_SIZE - 1, "\n");
	OutputDebugStringA(strBuf);
	GlobalFree(strBuf);
}


工程代码:
KiwifruitShell.rar

其中:myshell是壳源,kiwifruit_shell,是加壳的程序

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 79
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
也在学习研究逆向  已进群
2015-11-11 23:09
0
雪    币: 96
活跃值: (36)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
欢迎
2015-11-11 23:29
0
雪    币: 38
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
正在看滴水的教程,题主有他们的习题么??
2015-11-12 22:48
0
雪    币: 96
活跃值: (36)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
视频里面有留作业,但是没有参考答案,所以蛋疼除了问题,很难解决
2015-11-12 23:13
0
雪    币: 216
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
代码写得好乱,不是无聊就真看不下去了,
  //拷贝pe所有的头信息
  memcpy(pbyImageBuff, pbyFileBuff, pOptHeader->SizeOfHeaders);
这个不需要,ZwUnmapViewOfSection卸载区块,你填充区块进去,改下入口就行了
2015-11-13 14:28
0
雪    币: 94
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
群号错误了吗  怎么搜不到呢
2015-12-23 10:02
0
游客
登录 | 注册 方可回帖
返回
//