首页
社区
课程
招聘
[求助]加壳后的程序打不开.
发表于: 2022-2-6 06:34 14643

[求助]加壳后的程序打不开.

2022-2-6 06:34
14643

我写了个加壳程序,写完之后可以存盘.但是shellcode写入的地方应该是第一个节在内存中空闲的位置,但是我用PEtool打开发现却是在第二个节里。而且用Winhex打开的时候shellcode在文件的地址是C00,我将其根据FOA转RVA之后得到的数值跟程序原本计算的OEP地址也不一样。求大佬帮忙解决。小白万分感谢

VOID ShellCode()
{
	//可以通过硬编码,将要执行的函数全抠出来扔到这个Shellcode数组里
	BYTE Shellcode[] =
	{
		0X6A,0X00,0X6A,0X00,0X6A,0X00,0X6A,0X00,
		0XE8,0X00,0X00,0X00,0X00,
		0XE9,0X00,0X00,0X00,0X00
	};
	DWORD ShellcodeSize = sizeof(Shellcode);
	cout << "ShellcodeSize大小:"  << hex<<ShellcodeSize<< endl;;

	LPVOID LS= FileBufferToImageBuffer();                                                   //拉伸后的空间返回的地址
	PIMAGE_DOS_HEADER LSDOS = (PIMAGE_DOS_HEADER)LS;
	PIMAGE_NT_HEADERS LSNT = (PIMAGE_NT_HEADERS)((char*)LS + LSDOS->e_lfanew);
	PIMAGE_FILE_HEADER LSFILE = (PIMAGE_FILE_HEADER)((char*)LS + LSDOS->e_lfanew + 4);
	PIMAGE_OPTIONAL_HEADER64 LSOP64 = (PIMAGE_OPTIONAL_HEADER64)((char*)LS + LSDOS->e_lfanew + 4+IMAGE_SIZEOF_FILE_HEADER);
	PIMAGE_SECTION_HEADER LSSEC = (PIMAGE_SECTION_HEADER)((char*)LS + LSDOS->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER + LSFILE->SizeOfOptionalHeader);
	for (int i = 0; i < LSFILE->NumberOfSections; i++)
	{
		if (ShellcodeSize < LSSEC[i].SizeOfRawData - LSSEC[i].Misc.VirtualSize)
		{
			printf("第%x个节%s可以注入\n", i + 1, LSSEC[i].Name);                           //判断哪个节可以注入
		}
		else
		{
			printf("第%x个节%s不可以注入\n", i + 1, LSSEC[i].Name);                         //判断哪个节不可以注入
		}
	}

	LPVOID PointMessage = NULL;
	PointMessage = &MessageBoxA;
	printf("MessageBoxA在内存中的地址是%lx\n", PointMessage);
	//printf("写死的MessageBoxAddr的地址是%lx\n", MessageBoxAddr);

	for (int i = 0; i < LSFILE->NumberOfSections; i++)
	{
		if (ShellcodeSize < LSSEC[i].SizeOfRawData - LSSEC[i].Misc.VirtualSize)  //判断注入空间大小是否满足  shellcode代码长度<文件对齐后大小-文件对齐前的大小
		{

			printf("从第%x个节%s注入\n", i + 1, LSSEC[i].Name);
			//CodeBegin
			char* CodeBegin = (char*)((DWORD)LS + LSSEC[i].VirtualAddress + LSSEC[i].Misc.VirtualSize);  //代码注入开始的地方,Imagebuff 既节的内存偏移+节的尺寸
			printf("代码开始注入的内存地址是%lx\n", CodeBegin);
			memcpy(CodeBegin, Shellcode, ShellcodeSize); //把shellcode的代码从数组里拷贝到拉伸的内存中

			
			char* E8 = ((char*)CodeBegin + 0X9);
			char* E8next = ((char*)CodeBegin + 0XD);
			//X=MessageBoxA的地址-E8下一条在内存中的地址—>MessageBoxA-(E8当前地址-buff=得到的偏移+实际中的内存)  
			DWORD X = ((DWORD)PointMessage - ((DWORD)E8next - (DWORD)LS + (DWORD)LSOP64->ImageBase));  //得到E8下一条指令真正在内存中运行的地址
			printf("E8里X的数值=%lx\n", X);
			//改E8 将E8改成PDWORD的地址然后取值,取到的就是DWORD数据类型,然后将X的值写入
			*(PDWORD)(E8) = X;
			printf("E8的数值是%lx,X的数值是%lx\n", *(PDWORD)(E8), X);

		
			
			/*这个Y = OEP - E9下一条指令的地址并不是正确的
			//  错误的是:Y=OEP-E9下一条指令在内存中的地址 
			//  正确的是:Y=内存目标地址-E9下一条指令在内存中的地址     
			//这里有个非常重要的知识点 Y=目标地址-E9下一条在内存中的地址,所以我们不能单单拿OEP去减掉他的数值,而是将 ImageBase+OEP
			//因为 ImageBase+OEP才是我们要跳转的目标地址,这个地址是在内存中的,所以我们要加上内存基址 ImageBase
			//而E9下一条在内存中的地址是(DWORD)(((DWORD)E9next - (DWORD)LS) + LSOP64->ImageBase)) 是将E9下一条指令的地址-我们申请空间
			//的基本地址然后加上真正的内存基址ImageBase,这样的数值才是E9下一条在内存中的地址   2022/2/6
			*/
			char* E9 = ((char*)CodeBegin + 0XE);  //E9地址
			char* E9next = ((char*)CodeBegin + ShellcodeSize);//E9下一条指令的地址
			DWORD Y = ((DWORD)(LSOP64->ImageBase+LSOP64->AddressOfEntryPoint) - (DWORD)
			(((DWORD)E9next - (DWORD)LS) + LSOP64->ImageBase));
			printf("E9里X的数值=%lx\n", Y);
			//改E9 将E9改成PWORD的地址然后取值,取到的就是DWORD数据类型,然后将Y的值写入
			*(PDWORD)(E9) = Y;
			printf("E9的数值是%lx,Y的数值是%lx\n", *(PDWORD)(E9), Y);

			//改OEP
			printf("修改前的OEP=%lx\n", LSOP64->AddressOfEntryPoint);
			LSOP64->AddressOfEntryPoint = (DWORD)CodeBegin - (DWORD)LS;
			printf("修改后的OEP=%lx\n", LSOP64->AddressOfEntryPoint);
			break; 

			
		}
		else
		{
			printf("Shellcode注入的空间不够\n");
			break;
		}

	}
	//return LS;
	cout << "shellcode函数执行结束" << endl;
	LPVOID shellcodebuffer = ImageBufferToNewBuffer(LS);  //把注入好shellcode后的ImageBuffer压缩成Newbuffer
	FileSave(shellcodebuffer);
	
}


求大神解答 困扰了我好多天。。。

万分感谢!

/(ㄒoㄒ)/~~


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

最后于 2022-2-6 06:39 被白嫖怪编辑 ,原因: 添加附件
上传的附件:
收藏
免费 1
支持
分享
最新回复 (4)
雪    币: 3204
活跃值: (5429)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
我以前找那个”金牌服务“就是出现这个情况,找人看了下,原来是那个金牌服务又给软件加了一层壳子,骗我说没加壳子,呵呵
2022-2-6 16:49
0
雪    币: 159
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
zylrocket 我以前找那个”金牌服务“就是出现这个情况,找人看了下,原来是那个金牌服务又给软件加了一层壳子,骗我说没加壳子,呵呵
什么情况来的大佬.我这个shellcode是自己码的,我从堆栈里跟了整个程序好像也没问题,应该不会有多重壳的问题吧。。
2022-2-6 23:18
0
雪    币: 4378
活跃值: (4368)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
VOID ShellCode()
{
    //可以通过硬编码,将要执行的函数全抠出来扔到这个Shellcode数组里
    BYTE Shellcode[] =
    {
        0X6A,0X00,0X6A,0X00,0X6A,0X00,0X6A,0X00,
        0XE8,0X00,0X00,0X00,0X00,
        0XE9,0X00,0X00,0X00,0X00
    };
    DWORD ShellcodeSize = sizeof(Shellcode);
    cout << "ShellcodeSize大小:"  << hex<<ShellcodeSize<< endl;;
 
    LPVOID LS= FileBufferToImageBuffer();                                                   //拉伸后的空间返回的地址
    PIMAGE_DOS_HEADER LSDOS = (PIMAGE_DOS_HEADER)LS;
    PIMAGE_NT_HEADERS LSNT = (PIMAGE_NT_HEADERS)((char*)LS + LSDOS->e_lfanew);
    PIMAGE_FILE_HEADER LSFILE = (PIMAGE_FILE_HEADER)((char*)LS + LSDOS->e_lfanew + 4);
    
    //你这句在搞什么东东????  你读 x86 的代码 就不要用 x64的结构   x86是x86  x64是x64
    PIMAGE_OPTIONAL_HEADER64 LSOP64 = (PIMAGE_OPTIONAL_HEADER64)((char*)LS + LSDOS->e_lfanew + 4+IMAGE_SIZEOF_FILE_HEADER);

错误在此!

PIMAGE_OPTIONAL_HEADER64 LSOP64 = (PIMAGE_OPTIONAL_HEADER64)((char*)LS + LSDOS->e_lfanew + 4+IMAGE_SIZEOF_FILE_HEADER);


修改在此!

PIMAGE_OPTIONAL_HEADER32 LSOP64 = (PIMAGE_OPTIONAL_HEADER)((char*)LS + LSDOS->e_lfanew + 4+IMAGE_SIZEOF_FILE_HEADER);

2022-2-23 09:12
0
雪    币: 159
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
Mxixihaha VOID&nbsp;ShellCode() { &nbsp;&nbsp;&nbsp;&nbsp;//可以通过硬编码,将要执行的函数全抠出来扔到这个Shell ...
谢谢大佬,我前阵子复查了好久才发现的。非常感谢哈O(∩_∩)O
2022-3-11 19:33
0
游客
登录 | 注册 方可回帖
返回
//