本帖最后由 richard_ljd 于 2024-9-17 08:25 编辑
问题解决了
我命名的变量名codebegin把自己迷惑住了,那个只是在FIlebuffer文件状态下的地址,要写入内存状态的地址才行,
因为我自己命名时codebegin,我以为已经算的是Imagebuffer的地址,结果少了一个Imagebase,所以一直有错,函数改了一下就好了
[C++] 纯文本查看 复制代码 //复制CALL,且计算 MESSAGEBOX_WZ - (CALL + 5)实际参数,计算下一句地址需要 - PointerToRawData + VirtualAddress得到内存状态实际地址
int call_s = MESSAGEBOXW_WZ - (pOptionHeader->ImageBase + codebegin + 0xD); //<------------这里
BYTE c_wz[4];
mitol(call_s, c_wz);
memcpy(Shellcode + 0x9, c_wz, 4);
==================================================================================
最近在看教程,老师让用代码的方式自动在程序中写入ShellCode,且能够运行
在手动写入了以后,我也开始了代码写入,先简单来说一下过程
首先程序读入exe文件到FileBuffer,然后进行PE分析,分析完毕以后将FileBuffer转变成ImageBuffer,
随后我将我的ShellCode在这个ImageBuffer中寻找有空闲区域的节(防止自己写入的代码被覆盖),找到以后VirtualAddress + VirtualSize可以到节尾,
[C++] 纯文本查看 复制代码
BYTE Shellcode[] =
{
0x6A,00,0x6A,00,0x6A,00,0x6A,00,
0xE8,00,00,00,00,
0xE9,00,00,00,00
};
int PeHeader::AddShellcode(int Number)
{
int fsize = 0;
//遍历节,看是否有可以写入的节区
for (Number - 1; Number < pPEHeader->NumberOfSections; Number++)
{
fsize = (pSectionHeader + Number)->SizeOfRawData - (pSectionHeader + Number)->Misc.VirtualSize;
if (fsize > Shellcode_length)
break;
if (Number == pPEHeader->NumberOfSections - 1)
return 0;
}
int codebegin = (pSectionHeader + Number)->VirtualAddress + (pSectionHeader + Number)->Misc.VirtualSize;
//复制CALL,且计算 MESSAGEBOX_WZ - (CALL + 5)实际参数,计算下一句地址需要 - PointerToRawData + VirtualAddress得到内存状态实际地址
int call_s = MESSAGEBOXW_WZ - (codebegin + 0xE);
BYTE c_wz[4];
mitol(call_s, c_wz);
memcpy(Shellcode + 0x9, c_wz, 4);
//复制JMP,且计算 OEP - (JMP + 5)实际参数
int jmp_s = pOptionHeader->AddressOfEntryPoint - (codebegin + 18);
BYTE j_wz[4];
mitol(jmp_s, j_wz);
memcpy(Shellcode + 0xE, j_wz, 4);
//修改OEP,指向添加代码的位置
BYTE OEP[4];
mitol((pSectionHeader + Number)->Misc.VirtualSize + (pSectionHeader + Number)->VirtualAddress, OEP);
memcpy((void*)((DWORD)pNewBuffer + ((DWORD)pOptionHeader - (DWORD)pDosHeader) + 0x10), OEP, 4);
//将计算好的ShellCode写入pNewBuffer
memcpy((void*)((DWORD)pNewBuffer + codebegin), Shellcode, 18);
return pOptionHeader->AddressOfEntryPoint;
}
然后如上面这个代码段,添加CALL和JMP的地址,修改OEP
代码方面计算基本没有问题(实际有问题,也是这个帖子发出来的原因,不过先继续)
程序跑起来以后,直接运行引发未知错误直接结束,所以我挂上dbg
这个报错提示告诉我:1.指针为空 2.数组越界 3.堆栈溢出 4.内存损坏 5.硬件问题 6.无权限
这六个可能中前5个不好评价,第六个的话也不清楚怎么办(但是应该好歹调试器里面会显示到正确的位置吧)
于是我打算进程序里面看看,跟着jmp走了一会跳进了程序
这边用的是FF15,我尝试改成E8
发现也是可以的,但是回到我的Shellcode就直接炸了,不清楚为什么
下面是完整的代码,能Filebuffer和Imagebuffer相互转换,然后就没什么了()
微云网盘:https://share.weiyun.com/lVcTTb6Q
百度网盘:https://pan.baidu.com/s/1Y4XIVcBEDwEpQE2O9SES_A 提取码:1234
|