首页
社区
课程
招聘
[未解决,已结帖] [求助]求教一下内存中运行exe的各种问题 50.00雪花
发表于: 2019-10-30 10:57 2472

[未解决,已结帖] [求助]求教一下内存中运行exe的各种问题 50.00雪花

2019-10-30 10:57
2472
最近小弟有个需求,实现一个exe内存加载器,网上google啥的搜了一圈,试了各种代码,有的是借助傀儡进程,有的说没有重定位表无法内存加载,有的是xp上好使,7 10上不好使,这是为什么呢,请教一下各位实现这个功能要注意的各种问题,另外如果有现成的32 64位加载任意exe的现成代码我可付费借鉴学习  谢谢大家

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (14)
雪    币: 311
活跃值: (26)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
好安静 大家
2019-10-30 12:51
0
雪    币: 4522
活跃值: (5154)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
3
多少钱
2019-10-30 13:24
0
雪    币: 914
活跃值: (2468)
能力值: ( LV5,RANK:68 )
在线值:
发帖
回帖
粉丝
4
@山总@SKILL@东阳不列山@吴建文 你有生意了
2019-10-30 14:16
0
雪    币: 311
活跃值: (26)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
万剑归宗 @山总@SKILL@东阳不列山@吴建文 你有生意了
2019-10-30 14:34
0
雪    币: 311
活跃值: (26)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
sonyps 多少钱
你说
2019-10-30 14:37
0
雪    币: 7065
活跃值: (3106)
能力值: ( LV4,RANK:52 )
在线值:
发帖
回帖
粉丝
7
32位的好弄,64位的不好弄,不过也不是完全没法弄,32位的先根据PE头,铺到一个内存块里,然后构造好栈,之后ret,栈里面实现的是连续调用。
第一步,解除当前进程地址空间的引用。
第二步,申请需要的基址的地址。
第三步,把铺的内存地址中的数据拷回来。
第五步,跳到PE入口点。
大致的思路就是这样,其他的像导入表什么的,自己搞吧搞吧就出来了。
2019-10-30 14:40
0
雪    币: 226
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
VOID FixImageIAT(PIMAGE_DOS_HEADER dos_header, PIMAGE_NT_HEADERS nt_header)
{
	PIMAGE_THUNK_DATA thunk;
	PIMAGE_THUNK_DATA fixup;
	DWORD iat_rva;
	SIZE_T iat_size;
	HMODULE import_base;
	PIMAGE_IMPORT_DESCRIPTOR import_table =
		(PIMAGE_IMPORT_DESCRIPTOR)(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress +
		(UINT_PTR)dos_header);

	DWORD iat_loc =
		(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress) ?
		IMAGE_DIRECTORY_ENTRY_IAT :
		IMAGE_DIRECTORY_ENTRY_IMPORT;

	iat_rva = nt_header->OptionalHeader.DataDirectory[iat_loc].VirtualAddress;
	iat_size = nt_header->OptionalHeader.DataDirectory[iat_loc].Size;

	LPVOID iat = (LPVOID)(iat_rva + (UINT_PTR)dos_header);
	DWORD op;
	VirtualProtect(iat, iat_size, PAGE_READWRITE, &op);
	__try {
		while (import_table->Name) {
			import_base = LoadLibraryA((LPCSTR)(import_table->Name + (UINT_PTR)dos_header));
			fixup = (PIMAGE_THUNK_DATA)(import_table->FirstThunk + (UINT_PTR)dos_header);
			if (import_table->OriginalFirstThunk) {
				thunk = (PIMAGE_THUNK_DATA)(import_table->OriginalFirstThunk + (UINT_PTR)dos_header);
			}
			else {
				thunk = (PIMAGE_THUNK_DATA)(import_table->FirstThunk + (UINT_PTR)dos_header);
			}

			while (thunk->u1.Function) {
				PCHAR func_name;
				if (thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64) {
					fixup->u1.Function =
						(UINT_PTR)GetProcAddress(import_base, (LPCSTR)(thunk->u1.Ordinal & 0xFFFF));

				}
				else {
					func_name =
						(PCHAR)(((PIMAGE_IMPORT_BY_NAME)(thunk->u1.AddressOfData))->Name + (UINT_PTR)dos_header);
					fixup->u1.Function = (UINT_PTR)GetProcAddress(import_base, func_name);
				}
				fixup++;
				thunk++;
			}
			import_table++;
		}
	}
	__except (1) {

	}
	return;
}

//works with manually mapped files
HANDLE GetImageActCtx(HMODULE module)
{
	WCHAR temp_path[MAX_PATH];
	WCHAR temp_filename[MAX_PATH];
	for (int i = 1; i <= 3; i++) {
		HRSRC resource_info = FindResource(module, MAKEINTRESOURCE(i), RT_MANIFEST);
		if (resource_info) {
			HGLOBAL resource = LoadResource(module, resource_info);
			DWORD resource_size = SizeofResource(module, resource_info);
			const PBYTE resource_data = (const PBYTE)LockResource(resource);
			if (resource_data && resource_size) {
				FILE *fp;
				errno_t err;
				DWORD ret_val = GetTempPath(MAX_PATH, temp_path);

				if (0 == GetTempFileName(temp_path, L"manifest.tmp", 0, temp_filename))
					return NULL;

				err = _wfopen_s(&fp, temp_filename, L"w");

				if (errno)
					return NULL;

				fprintf(fp, (const char *)resource_data);
				fclose(fp);
				break;
			}
			else {
				return NULL;
			}
		}
	}

	ACTCTXW act = { sizeof(act) };
	act.lpSource = temp_filename;
	return CreateActCtx(&act);
}

//if base_addr points to a byte stream in memory then load module from that
//if base_addr is NULL then attempt to map module into memory from resource
//***note if module is memory mapped manually then it has no loaded module handle 
//and some modules use the module base as the handle for a call and it will fail
LPVOID MapImageToMemory(LPVOID base_addr)
{
	LPVOID mem_image_base = NULL;
	__try {

		PIMAGE_DOS_HEADER raw_image_base = (PIMAGE_DOS_HEADER)base_addr;
		if (!base_addr) {
			HMODULE proc_base = GetModuleHandle(NULL);
			HRSRC resource_info = FindResource(proc_base, MAKEINTRESOURCE(IDR_EXE_FILE1), L"exe_file"); //add your own resource
			if (resource_info) {
				HGLOBAL resource = LoadResource(proc_base, resource_info);
				DWORD resource_size = SizeofResource(proc_base, resource_info);
				const PBYTE resource_data = (const PBYTE)LockResource(resource);
				raw_image_base = (PIMAGE_DOS_HEADER)LockResource(resource);
			}
		}

		if (IMAGE_DOS_SIGNATURE != raw_image_base->e_magic)
			return NULL;

		PIMAGE_NT_HEADERS nt_header = (PIMAGE_NT_HEADERS)(raw_image_base->e_lfanew + (UINT_PTR)raw_image_base);
		if (IMAGE_NT_SIGNATURE != nt_header->Signature)
			return NULL;

		//only 64bit modules will be loaded
		if (IMAGE_FILE_MACHINE_AMD64 != nt_header->FileHeader.Machine)
			return NULL;

		//Not going to bother with .net
		if (nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress)
			return NULL;

		PIMAGE_SECTION_HEADER section_header =
			(PIMAGE_SECTION_HEADER)(raw_image_base->e_lfanew + sizeof(*nt_header) + (UINT_PTR)raw_image_base);

		mem_image_base = VirtualAlloc(
			(LPVOID)(nt_header->OptionalHeader.ImageBase),
			nt_header->OptionalHeader.SizeOfImage,
			MEM_COMMIT | MEM_RESERVE,
			PAGE_EXECUTE_READWRITE);

		if (NULL == mem_image_base) {
			mem_image_base = VirtualAlloc(
				NULL,
				nt_header->OptionalHeader.SizeOfImage,
				MEM_COMMIT | MEM_RESERVE,
				PAGE_EXECUTE_READWRITE);
		}

		if (NULL == mem_image_base)
			return NULL;

		memcpy(mem_image_base, (LPVOID)raw_image_base, nt_header->OptionalHeader.SizeOfHeaders);

		for (int i = 0; i < nt_header->FileHeader.NumberOfSections; i++) {
			memcpy(
				(LPVOID)(section_header->VirtualAddress + (UINT_PTR)mem_image_base),
				(LPVOID)(section_header->PointerToRawData + (UINT_PTR)raw_image_base),
				section_header->SizeOfRawData);
			section_header++;
		}
	}
	__except (1) {

	}
	return mem_image_base;
}

BOOL FixImageRelocations(PIMAGE_DOS_HEADER dos_header, PIMAGE_NT_HEADERS nt_header, ULONG_PTR delta)
{
	ULONG_PTR size;
	PULONG_PTR intruction;
	PIMAGE_BASE_RELOCATION reloc_block =
		(PIMAGE_BASE_RELOCATION)(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress +
		(UINT_PTR)dos_header);

	while (reloc_block->VirtualAddress) {
		size = (reloc_block->SizeOfBlock - sizeof(reloc_block)) / sizeof(WORD);
		PWORD fixup = (PWORD)((ULONG_PTR)reloc_block + sizeof(reloc_block));
		for (int i = 0; i < size; i++, fixup++) {
			if (IMAGE_REL_BASED_DIR64 == *fixup >> 12) {
				intruction = (PULONG_PTR)(reloc_block->VirtualAddress + (ULONG_PTR)dos_header + (*fixup & 0xfff));
				*intruction += delta;
			}
		}
		reloc_block = (PIMAGE_BASE_RELOCATION)(reloc_block->SizeOfBlock + (ULONG_PTR)reloc_block);
	}
	return TRUE;
}


int load_main()
{
	//three options for loading the image from either 1.memory array 2.resource 3.file
	PIMAGE_DOS_HEADER image_base = (PIMAGE_DOS_HEADER)MapImageToMemory((LPVOID)NULL);
	//PIMAGE_DOS_HEADER image_base = (PIMAGE_DOS_HEADER)MapImageToMemory(NULL);//not working with some files like notepad etc
	//PIMAGE_DOS_HEADER image_base = (PIMAGE_DOS_HEADER)LoadLibrary(L"target.exe");//works
	if (!image_base) {
		return 1;
	}

	PIMAGE_NT_HEADERS nt_header = (PIMAGE_NT_HEADERS)(image_base->e_lfanew + (UINT_PTR)image_base);
	HANDLE actctx = NULL;
	UINT_PTR cookie = 0;
	BOOL changed_ctx = FALSE;
	if (nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress) {
		actctx = GetImageActCtx((HMODULE)image_base);
		if (actctx)
			changed_ctx = ActivateActCtx(actctx, &cookie);
	}

	FixImageIAT(image_base, nt_header);

	if (nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) {
		ptrdiff_t delta = (ptrdiff_t)((PBYTE)image_base - (PBYTE)nt_header->OptionalHeader.ImageBase);
		if (delta)
			FixImageRelocations(image_base, nt_header, delta);
	}

	LPVOID oep = (LPVOID)(nt_header->OptionalHeader.AddressOfEntryPoint + (UINT_PTR)image_base);
	((void(*)())(oep))();
	//DWORD tid;
	//PCONTEXT ctx;
	//CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)oep, NULL, 0, &tid);

	if (changed_ctx) {
		DeactivateActCtx(0, cookie);
		ReleaseActCtx(actctx);
	}

	return 0;
}

64位的, 插入资源即可, 或者修改为内存


2019-10-30 15:28
0
雪    币: 226
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
vmp可以用这种方式破解文件校验
最后于 2019-10-30 15:32 被deadash编辑 ,原因:
2019-10-30 15:30
0
雪    币: 4522
活跃值: (5154)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
10
tudouer 你说[em_85]
私信你了,完美,不写文件,兼容x86,x64甚至Windows arm64也可以兼容,支持windows2000及以后版本的操作系统
2019-10-30 16:22
0
雪    币: 311
活跃值: (26)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
11
sonyps 私信你了,完美,不写文件,兼容x86,x64甚至Windows arm64也可以兼容,支持windows2000及以后版本的操作系统
通过一下 老哥
2019-10-30 16:57
0
雪    币: 311
活跃值: (26)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
12
deadash VOID&nbsp;FixImageIAT(PIMAGE_DOS_HEADER&nbsp;dos_header,&nbsp;PIMAGE_NT_HEADERS&nbsp ...
win10 上好像测试不行
2019-10-30 16:58
0
雪    币: 311
活跃值: (26)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
13
老哥的源码太贵 小弟买不起呀买不起  哎  还有大佬能指点一二吗
2019-10-30 17:12
0
雪    币: 226
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
tudouer win10 上好像测试不行
我就是在win10上面测试的,x64,完全ok
2019-11-10 11:42
0
雪    币: 30
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
内存加载dll啊,原理一样,dll是加载完后执行dllmain,exe就是跳到入口点
2019-11-11 08:25
0
游客
登录 | 注册 方可回帖
返回
//